crvUSDsim: Python Simulator for Curve Stablecoin¶
Release v0.1.0. (Installation)
Pythonic interaction with Curve Stablecoin market objects (include LLAMMA pool, controller, aggregator, PegKeepers, etc.):
>>> import crvusdsim
>>> (pool, controller, collateral_token, stablecoin, aggregator, price_oracle, stableswap_pools, peg_keepers, policy, factory)
>>> = crvusdsim.pool.get(market_name, bands_data="controller")
>>> pool.name
'Curve.fi Stablecoin wstETH'
>>> pool.coin_names
['wstETH', 'crvUSD']
>>> pool.A
100
>>> sum(pool.bands_x.values())
0
>>> sum(pool.bands_y.values())
40106052164494685140992
>>> len(pool.user_shares)
392
>>> dx = 10**18
>>> pool.trade(0, 1, dx) # dx, dy, fees
(1000000000000000000, 445225238462727, 6000000000000000)
>>> controller.loan_discount
90000000000000000
>>> controller.liquidation_discount
60000000000000000
>>> len(controller.loan)
392
>>> user0 = controller.loans[1] # user address
>>> loan0 = controller.loan[user0] # :class:Loan
>>> (loan0.initial_debt, loan0.initial_collateral, loan0.rate_mul, loan0.timestamp)
(9779961749290509154648064, 6785745612366175797248, 1000000000000000000, 1700712599)
Arbitrage simulations to see results of varying fee and amplification (A) parameters in LLAMMA pool:
>>> import crvusdsim
>>> res = crvusdsim.autosim(pool="wstETH", sim_mode="pool", A=[50, 60, 80, 100])
[INFO][14:57:58][crvusdsim.pipelines.simple]-82656: Simulating mode: pool
[INFO][14:58:00][curvesim.price_data.sources]-82656: Fetching CoinGecko price data...
[INFO][14:58:05][crvusdsim.templates.Strategy]-82729: [Curve.fi Stablecoin wstETH] Simulating with {'A': 50}
[INFO][14:58:05][crvusdsim.templates.Strategy]-82730: [Curve.fi Stablecoin wstETH] Simulating with {'A': 100}
[INFO][14:58:05][crvusdsim.templates.Strategy]-82731: [Curve.fi Stablecoin wstETH] Simulating with {'A': 60}
[INFO][14:58:05][crvusdsim.templates.Strategy]-82732: [Curve.fi Stablecoin wstETH] Simulating with {'A': 80}
>>> res.summary()
metric pool_value arb_profits_percent pool_volume arb_profit pool_fees
stat annualized_returns annualized_arb_profits sum sum sum
0 0.411643 -0.027450 4.558058e+09 9.609988e+06 6.034716e+07
1 0.417621 -0.027471 4.510472e+09 9.859186e+06 5.982183e+07
2 0.415172 -0.027779 4.576752e+09 1.003158e+07 6.063303e+07
3 0.409765 -0.028545 4.521058e+09 1.003305e+07 5.995173e+07
>>> res.data()
run timestamp pool_value arb_profits_percent pool_volume arb_profit pool_fees
0 0 2023-09-18 23:30:00+00:00 1.799787e+09 -0.000552 40480.098668 993516.570233 455541.247191
1 0 2023-09-18 23:38:34+00:00 1.799580e+09 -0.000552 0.000000 0.000000 0.000000
2 0 2023-09-18 23:47:08+00:00 1.799374e+09 -0.000552 0.000000 0.000000 0.000000
3 0 2023-09-18 23:55:42+00:00 1.799167e+09 -0.000552 0.000000 0.000000 0.000000
4 0 2023-09-19 00:04:17+00:00 1.798961e+09 -0.000552 0.000000 0.000000 0.000000
... ... ... ... ... ... ... ...
40991 3 2023-11-18 22:55:42+00:00 1.922090e+09 -0.005379 0.000000 0.000000 0.000000
40992 3 2023-11-18 23:04:17+00:00 1.922090e+09 -0.005379 0.000000 0.000000 0.000000
40993 3 2023-11-18 23:12:51+00:00 1.922090e+09 -0.005379 0.000000 0.000000 0.000000
40994 3 2023-11-18 23:21:25+00:00 1.922090e+09 -0.005379 0.000000 0.000000 0.000000
40995 3 2023-11-18 23:30:00+00:00 1.922090e+09 -0.005379 0.000000 0.000000 0.000000
40996 rows x 7 columns
Arbitrage simulations to see results of varying loan_discount and liquidation_discount parameters in Controller:
>>> loan_discounts = [int(d * 10**18) for d in [0.09, 0.10, 0.11, 0.12]]
>>> res = crvusdsim.autosim(pool="wstETH", sim_mode="controller", loan_discount=loan_discounts, liquidation_discount=[int(0.06 * 10**18)])
[INFO][17:01:13][crvusdsim.pipelines.simple]-91016: Simulating mode: controller
[INFO][17:01:15][curvesim.price_data.sources]-91016: Fetching CoinGecko price data...
[INFO][17:02:56][crvusdsim.templates.Strategy]-91050: [Curve.fi Stablecoin wstETH] Simulating with {'loan_discount': 100000000000000000, 'liquidation_discount': 60000000000000000}
[INFO][17:02:56][crvusdsim.templates.Strategy]-91052: [Curve.fi Stablecoin wstETH] Simulating with {'loan_discount': 110000000000000000, 'liquidation_discount': 60000000000000000}
[INFO][17:02:56][crvusdsim.templates.Strategy]-91049: [Curve.fi Stablecoin wstETH] Simulating with {'loan_discount': 90000000000000000, 'liquidation_discount': 60000000000000000}
[INFO][17:02:56][crvusdsim.templates.Strategy]-91053: [Curve.fi Stablecoin wstETH] Simulating with {'loan_discount': 120000000000000000, 'liquidation_discount': 60000000000000000}
>>> res.summary()
metric averange_user_health liquidations_count liquidation_volume
stat mean max sum
0 0.027328 0.0 0.0
1 0.038743 0.0 0.0
2 0.050414 0.0 0.0
3 0.062351 0.0 0.0
>>> res.data()
run timestamp averange_user_health liquidations_count liquidation_volume
0 0 2023-09-18 23:30:00+00:00 0.036745 0.0 0.0
1 0 2023-09-18 23:38:34+00:00 0.036745 0.0 0.0
2 0 2023-09-18 23:47:08+00:00 0.036743 0.0 0.0
3 0 2023-09-18 23:55:42+00:00 0.036739 0.0 0.0
4 0 2023-09-19 00:04:17+00:00 0.036733 0.0 0.0
... ... ... ... ... ...
40991 3 2023-11-18 22:55:42+00:00 0.045240 0.0 0.0
40992 3 2023-11-18 23:04:17+00:00 0.045240 0.0 0.0
40993 3 2023-11-18 23:12:51+00:00 0.045240 0.0 0.0
40994 3 2023-11-18 23:21:25+00:00 0.045240 0.0 0.0
40995 3 2023-11-18 23:30:00+00:00 0.045240 0.0 0.0
40996 rows x 5 columns
Arbitrage simulations to see results of varying N of user’s position:
>>> res = crvusdsim.autosim(pool="wstETH", sim_mode="N", N=[4, 6, 8, 10, 20, 40, 50])
[INFO][17:17:50][crvusdsim.pipelines.simple]-91016: Simulating mode: N
[INFO][17:17:53][curvesim.price_data.sources]-91016: Fetching CoinGecko price data...
[INFO][17:17:59][crvusdsim.templates.Strategy]-91351: [Curve.fi Stablecoin wstETH] Simulating with {'N': 8}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91354: [Curve.fi Stablecoin wstETH] Simulating with {'N': 40}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91349: [Curve.fi Stablecoin wstETH] Simulating with {'N': 4}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91355: [Curve.fi Stablecoin wstETH] Simulating with {'N': 50}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91352: [Curve.fi Stablecoin wstETH] Simulating with {'N': 10}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91353: [Curve.fi Stablecoin wstETH] Simulating with {'N': 20}
[INFO][17:18:01][crvusdsim.templates.Strategy]-91350: [Curve.fi Stablecoin wstETH] Simulating with {'N': 6}
>>> res.summary()
metric user_value
stat annualized_returns
0 -0.228595
1 -0.168579
2 -0.129110
3 -0.104466
4 -0.053433
5 -0.027022
6 -0.021667
>>> res.data()
run timestamp user_value
0 0 2023-09-18 23:30:00+00:00 1.000000
1 0 2023-09-18 23:38:34+00:00 1.000000
2 0 2023-09-18 23:47:08+00:00 1.000000
3 0 2023-09-18 23:55:42+00:00 1.000000
4 0 2023-09-19 00:04:17+00:00 1.000000
... ... ... ...
71738 6 2023-11-18 22:55:42+00:00 0.996344
71739 6 2023-11-18 23:04:17+00:00 0.996344
71740 6 2023-11-18 23:12:51+00:00 0.996344
71741 6 2023-11-18 23:21:25+00:00 0.996344
71742 6 2023-11-18 23:30:00+00:00 0.996344
71743 rows x 3 columns
Features¶
crvUSDsim lets you:
Simulate interactions with A series of objects related to crvusd in Python (include LLAMMA pool, Controller, PegKeepers, etc).
Analyze the effects of parameter changes on pool performance
Develop custom simulation pipelines for pool optimization
User Guide¶
API Documentation¶
Contributor Guide¶
Issue Tracker: github.com/0xreviews/crvusdsim/issues
Source Code: github.com/0xreviews/crvusdsim
Support¶
If you are having issues, please let us know. You can reach us via the following
License¶
Portions of the codebase are authorized derivatives of code owned by Curve.fi (Swiss Stake GmbH). These are the vyper snippets used for testing and the python code derived from them (crvusdsim/pool/crvusd); there are copyright notices placed appropriately. The rest of the codebase has an MIT license.