Skip to content

Commit dd54560

Browse files
authored
Strategist runlogs to March 3 (#1254)
1 parent 2b51eeb commit dd54560

File tree

5 files changed

+787
-10
lines changed

5 files changed

+787
-10
lines changed

brownie/allocations.py

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747

4848

4949
def load_from_blockchain():
50+
meta_3pool_dollars = world.ousd_metapool.balances(1) * world.threepool.get_virtual_price() / 1e18
51+
meta_ousd_dollars = world.ousd_metapool.balances(0)
52+
meta_stables_mix = meta_3pool_dollars / (meta_ousd_dollars + meta_3pool_dollars)
53+
5054
base = pd.DataFrame.from_records(
5155
[
5256
["AAVE", "DAI", int(world.aave_strat.checkBalance(world.DAI) / 1e18)],
@@ -63,7 +67,10 @@ def load_from_blockchain():
6367
["MORPHO_AAVE", "USDT", int(world.morpho_aave_strat.checkBalance(world.USDT) / 1e6)],
6468
["CONVEX", "*", int(world.convex_strat.checkBalance(world.DAI) * 3 / 1e18)],
6569
["LUSD_3POOL", "*", int(world.lusd_3pool_strat.checkBalance(world.DAI) * 3 / 1e18)],
66-
["OUSD_META", "*", int(world.ousd_meta_strat.checkBalance(world.DAI) * 3 / 2 / 1e18)],
70+
["OUSD_META", "*", int(world.ousd_meta_strat.checkBalance(world.DAI) * 3 * meta_stables_mix / 1e18)],
71+
['VAULT','DAI', int(world.dai.balanceOf(world.vault_core)/ 1e18) ],
72+
['VAULT','USDC', int(world.usdc.balanceOf(world.vault_core)/ 1e6)],
73+
['VAULT','USDT', int(world.usdt.balanceOf(world.vault_core)/ 1e6)],
6774
],
6875
columns=["strategy", "token", "current_dollars"],
6976
)
@@ -86,6 +93,32 @@ def reallocate(from_strat, to_strat, funds):
8693
coins.append(coin)
8794
return world.vault_admin.reallocate(from_strat, to_strat, coins, amounts, {"from": world.STRATEGIST})
8895

96+
def from_strat(from_strat, funds):
97+
"""
98+
Execute and return a transaction reallocating funds from one strat to another
99+
"""
100+
if isinstance(from_strat, str) and from_strat[0:2] != "0x":
101+
from_strat = NAME_TO_STRAT[from_strat]
102+
amounts = []
103+
coins = []
104+
for [dollars, coin] in funds:
105+
amounts.append(int(dollars * 10 ** coin.decimals()))
106+
coins.append(coin)
107+
return world.vault_admin.withdrawFromStrategy(from_strat, coins, amounts, {"from": world.STRATEGIST})
108+
109+
def to_strat(to_strat, funds):
110+
"""
111+
Execute and return a transaction depositing to a strat
112+
"""
113+
if isinstance(to_strat, str) and to_strat[0:2] != "0x":
114+
to_strat = NAME_TO_STRAT[to_strat]
115+
amounts = []
116+
coins = []
117+
for [dollars, coin] in funds:
118+
amounts.append(int(dollars * 10 ** coin.decimals()))
119+
coins.append(coin)
120+
return world.vault_admin.depositToStrategy(to_strat, coins, amounts, {"from": world.STRATEGIST})
121+
89122

90123
def allocation_exposure(allocation):
91124
"""
@@ -147,9 +180,17 @@ def __exit__(self, *args, **kwargs):
147180
else:
148181
vault_change = world.vault_core.totalValue() - self.before_vault_value
149182
supply_change = world.ousd.totalSupply() - self.before_total_supply
150-
after_allocaiton = with_target_allocations(load_from_blockchain(), self.before_votes)
151-
print(pretty_allocations(after_allocaiton))
152-
allocation_exposure(after_allocaiton)
183+
after_allocation = with_target_allocations(load_from_blockchain(), self.before_votes)
184+
print(pretty_allocations(after_allocation))
185+
print("Coin deltas to target")
186+
print(after_allocation.groupby('token')['delta_dollars'].sum().apply("{:,}".format))
187+
allocation_exposure(after_allocation)
188+
189+
print('Vault Direct Holdings:')
190+
print(" DAI", world.c18(world.dai.balanceOf(world.vault_core)))
191+
print(" USDC", world.c6(world.usdc.balanceOf(world.vault_core)))
192+
print(" USDT", world.c6(world.usdt.balanceOf(world.vault_core)))
193+
153194
show_default_strategies()
154195
print("Vault change", world.c18(vault_change))
155196
print("Supply change", world.c18(supply_change))
@@ -190,14 +231,17 @@ def with_target_allocations(allocation, votes):
190231
print(df["target_allocation"].sum())
191232
raise Exception("Target allocations total too low")
192233

193-
df["target_dollars"] = (
194-
df["current_dollars"].sum() * df["target_allocation"] / df["target_allocation"].sum()
195-
).astype(int)
234+
if isinstance(votes, pd.DataFrame):
235+
df["target_dollars"] = votes["target_dollars"]
236+
else:
237+
df["target_dollars"] = (
238+
df["current_dollars"].sum() * df["target_allocation"] / df["target_allocation"].sum()
239+
).astype(int)
196240
df["delta_dollars"] = df["target_dollars"] - df["current_dollars"]
197241
return df
198242

199243

200-
def pretty_allocations(allocation, close_enough=50_000):
244+
def pretty_allocations(allocation, close_enough=255_000):
201245
df = allocation.copy()
202246
df["s"] = ""
203247
df.loc[df["delta_dollars"].abs() < close_enough, "s"] = "✔︎"
@@ -206,7 +250,7 @@ def pretty_allocations(allocation, close_enough=50_000):
206250
df["current_dollars"] = df["current_dollars"].apply("{:,}".format)
207251
df["target_dollars"] = df["target_dollars"].apply("{:,}".format)
208252
df["delta_dollars"] = df["delta_dollars"].apply("{:,}".format)
209-
return df.sort_values("token")
253+
return df.sort_values("strategy")
210254

211255

212256
def net_delta(allocation):

brownie/runlogs/2023_01_strategist.py

Lines changed: 238 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,241 @@
397397
safe = ApeSafe('0xF14BBdf064E3F67f51cd9BD646aE3716aD938FDC')
398398
safe_tx = safe.multisend_from_receipts(txs)
399399
safe.sign_with_frame(safe_tx)
400-
r = safe.post_transaction(safe_tx)
400+
r = safe.post_transaction(safe_tx)
401+
402+
403+
# --------------------------------
404+
# Jan 26, 2023 - Weekly allocation
405+
# (new style protoype, not run)
406+
#
407+
408+
from addresses import *
409+
from world import *
410+
from allocations import *
411+
from ape_safe import ApeSafe
412+
413+
# Temp for local fork testing
414+
whale = accounts.at(BIGWALLET, force=True)
415+
unlock(whale.address)
416+
whale.transfer(STRATEGIST, 1e18)
417+
418+
votes = """
419+
Convex OUSD+3Crv 35.3%
420+
Morpho Compound USDC 32.09%
421+
Morpho Compound USDT 12.15%
422+
Morpho Aave USDT 11.96%
423+
Morpho Aave USDC 4.04%
424+
Aave DAI 0.24%
425+
Aave USDC 0.24%
426+
Aave USDT 0.24%
427+
Compound DAI 0.19%
428+
Compound USDC 0.19%
429+
Compound USDT 0.19%
430+
Convex LUSD+3Crv 0.19%
431+
Existing Allocation 0%
432+
Convex DAI+USDC+USDT 0%
433+
Morpho Aave DAI 3%
434+
Morpho Compound DAI 0%
435+
"""
436+
437+
with TemporaryForkWithVaultStats(votes):
438+
before_votes = with_target_allocations(load_from_blockchain(), votes)
439+
txs = []
440+
txs.extend(auto_take_snapshot())
441+
442+
# From
443+
from_strat(MORPHO_AAVE_STRAT,[[380_000, dai], [8_124_000, usdt]])
444+
from_strat(MORPHO_COMP_STRAT,[[864_000, dai]])
445+
from_strat(OUSD_META_STRAT,[[3_000_000, usdc]])
446+
447+
# Convert
448+
to_strat(CONVEX_STRAT,[[1_244_000, dai], [4_905_000, usdt]])
449+
from_strat(CONVEX_STRAT,[[7_149_000, usdc]])
450+
451+
# To
452+
to_strat(MORPHO_COMP_STRAT,[[10_149_000, usdc], [3_271_000, usdt]])
453+
txs.append(vault_admin.setAssetDefaultStrategy(usdc, MORPHO_COMP_STRAT, {'from':STRATEGIST}))
454+
txs.append(vault_admin.setAssetDefaultStrategy(usdt, MORPHO_COMP_STRAT, {'from':STRATEGIST}))
455+
456+
txs.extend(auto_check_snapshot())
457+
print("Est Gas Max: {:,}".format(1.10*sum([x.gas_used for x in txs])))
458+
459+
460+
safe = ApeSafe('0xF14BBdf064E3F67f51cd9BD646aE3716aD938FDC')
461+
safe_tx = safe.multisend_from_receipts(txs)
462+
safe.sign_with_frame(safe_tx)
463+
r = safe.post_transaction(safe_tx)
464+
465+
466+
# --------------------------------
467+
# Jan 30, 2023 - Weekly allocation
468+
#
469+
470+
from addresses import *
471+
from world import *
472+
from allocations import *
473+
from ape_safe import ApeSafe
474+
475+
votes = """
476+
Convex OUSD+3Crv 35.3%
477+
Morpho Compound USDC 32.09%
478+
Morpho Compound USDT 12.15%
479+
Morpho Aave USDT 11.96%
480+
Morpho Aave USDC 4.04%
481+
Aave DAI 0.24%
482+
Aave USDC 0.24%
483+
Aave USDT 0.24%
484+
Compound DAI 0.19%
485+
Compound USDC 0.19%
486+
Compound USDT 0.19%
487+
Convex LUSD+3Crv 0.19%
488+
Existing Allocation 0%
489+
Convex DAI+USDC+USDT 0%
490+
Morpho Aave DAI 3%
491+
Morpho Compound DAI 0%
492+
"""
493+
494+
with TemporaryForkWithVaultStats(votes):
495+
before_votes = with_target_allocations(load_from_blockchain(), votes)
496+
txs = []
497+
txs.extend(auto_take_snapshot())
498+
499+
txs.append(reallocate(MORPHO_AAVE_STRAT, MORPHO_COMP_STRAT, [[3_271_000, usdt]]))
500+
txs.append(reallocate(MORPHO_COMP_STRAT, MORPHO_AAVE_STRAT, [[864_000, dai]]))
501+
502+
# Swap
503+
txs.append(reallocate(MORPHO_AAVE_STRAT, CONVEX_STRAT, [[1_244_000, dai], [4_852_000, usdt]]))
504+
txs.append(reallocate(CONVEX_STRAT, MORPHO_COMP_STRAT, [[7_165_000, usdc]]))
505+
506+
# From meta
507+
txs.append(reallocate(OUSD_META_STRAT, MORPHO_COMP_STRAT, [[3_330_000, usdc]]))
508+
509+
txs.extend(auto_check_snapshot())
510+
print("Est Gas Max: {:,}".format(1.10*sum([x.gas_used for x in txs])))
511+
512+
513+
safe = ApeSafe('0xF14BBdf064E3F67f51cd9BD646aE3716aD938FDC')
514+
safe_tx = safe.multisend_from_receipts(txs)
515+
safe.sign_with_frame(safe_tx)
516+
r = safe.post_transaction(safe_tx)
517+
518+
519+
# --------------------------------
520+
# Jan 31, 2023 - Transfer OUSD
521+
#
522+
523+
from world import *
524+
525+
def make_governable(pair):
526+
return Contract.from_abi(pair[1], pair[0], buyback.abi)
527+
528+
def parse_contracts(s):
529+
out = []
530+
for line in s.split("\n"):
531+
tokens = line.split(" ")
532+
if len(tokens) == 2:
533+
g = make_governable(tokens)
534+
out.append(g)
535+
return out
536+
537+
538+
transfer_contracts = parse_contracts("""
539+
0x6C5cdfB47150EFc52072cB93Eea1e0F123529748 Buyback
540+
0x7294CD3C3eb4097b03E1A61EB2AD280D3dD265e6 Buyback
541+
0x77314EB392b2be47C014cde0706908b3307Ad6a9 Buyback
542+
0x2A8e1E676Ec238d8A992307B495b45B3fEAa5e86 OUSDProxy
543+
0xE75D77B1865Ae93c7eaa3040B038D7aA7BC02F70 VaultProxy
544+
0x9c459eeb3FA179a40329b81C1635525e9A0Ef094 InitializeGovernedUpgradeabilityProxy
545+
0x21Fb5812D70B3396880D30e90D9e5C1202266c89 HarvesterProxy
546+
0x80C898ae5e56f888365E235CeB8CEa3EB726CB58 HarvesterProxy
547+
0x5e3646A1Db86993f73E6b74A57D8640B69F7e259 InitializeGovernedUpgradeabilityProxy
548+
0xEA2Ef2e2E5A749D4A66b41Db9aD85a38Aa264cb3 ConvexStrategyProxy
549+
0x89Eb88fEdc50FC77ae8a18aAD1cA0ac27f777a90 ConvexUSDDMetaStrategyProxy
550+
0x5A4eEe58744D1430876d5cA93cAB5CcB763C037D MorphoCompoundStrategyProxy
551+
0x7A192DD9Cc4Ea9bdEdeC9992df74F1DA55e60a19 ConvexLUSDMetaStrategyProxy
552+
0x79F2188EF9350A1dC11A062cca0abE90684b0197 MorphoAaveStrategyProxy
553+
0xD2af830E8CBdFed6CC11Bab697bB25496ed6FA62 wOUSDProxy
554+
0x501804B374EF06fa9C427476147ac09F1551B9A0 InitializeGovernedUpgradeabilityProxy
555+
""")
556+
557+
accept_only_contracts = parse_contracts("""
558+
0x997c35A0bf8E21404aE4379841E0603C957138c3 VaultCore
559+
""")
560+
561+
# Another day: 0x52BEBd3d7f37EC4284853Fd5861Ae71253A7F428 OldTimelock
562+
563+
all_contracts = [*transfer_contracts, *accept_only_contracts]
564+
565+
# Pre-transfer old vault core
566+
g = make_governable(['0x997c35A0bf8E21404aE4379841E0603C957138c3', 'VaultCore'])
567+
g.transferGovernance(TIMELOCK, {'from': g.governor()})
568+
569+
570+
for c in all_contracts:
571+
print(c.governor(), c._name)
572+
573+
574+
# --- Old governor
575+
576+
with TemporaryFork():
577+
gov_txs = []
578+
for c in transfer_contracts:
579+
gov_txs.append(c.transferGovernance(TIMELOCK, {'from':GOVERNOR}))
580+
581+
governor.propose(
582+
[x.receiver for x in gov_txs],
583+
['transferGovernance(address)' for x in gov_txs],
584+
[x.input[10:] for x in gov_txs],
585+
"Transfer governance of OUSD to veOGV governance system",
586+
{'from': GOV_MULTISIG }
587+
)
588+
589+
print(history[-1].receiver)
590+
print(history[-1].input)
591+
print(history[-1].events)
592+
proposal_id = history[-1].events['ProposalCreated'][0]['id']
593+
print(proposal_id)
594+
595+
sim_governor_execute(proposal_id)
596+
597+
598+
# --- New governor
599+
600+
accept_txs = []
601+
with TemporaryFork():
602+
for c in all_contracts:
603+
accept_txs.append(c.claimGovernance({'from': TIMELOCK}))
604+
605+
governor_five.propose(
606+
[x.receiver for x in accept_txs],
607+
[0 for x in accept_txs],
608+
['claimGovernance()' for x in accept_txs],
609+
['' for x in accept_txs],
610+
"Claim governance of OUSD contracts\n\nAll OUSD governance contracts will be owned by the veOGV governance system.",
611+
{'from': GOV_MULTISIG }
612+
)
613+
614+
print("Raw proposal:")
615+
print(history[-1].receiver)
616+
print(history[-1].input)
617+
print(history[-1].events)
618+
proposal_id = history[-1].events['ProposalCreated'][0]['proposalId']
619+
print(proposal_id)
620+
621+
print("...Simulating vote")
622+
chain.mine()
623+
governor_five.castVote(proposal_id, 1, {'from': GOV_MULTISIG})
624+
625+
print("...Simulating voting time, going to take time")
626+
chain.mine(governor_five.votingPeriod() + 1)
627+
628+
print("...Simulating queue")
629+
governor_five.queue(proposal_id, {'from': GOV_MULTISIG})
630+
chain.mine(timedelta=2*24*60*60+2)
631+
632+
print("...Simulating execution")
633+
governor_five.execute(proposal_id, {'from': GOV_MULTISIG})
634+
635+
636+
for c in all_contracts:
637+
print(c.governor(), c._name)

0 commit comments

Comments
 (0)