Skip to content

Commit

Permalink
feat: several fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sajanrajdev committed Jun 19, 2024
1 parent 415ada1 commit 964625a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
8 changes: 7 additions & 1 deletion great_ape_safe/ape_api/uni_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def burn_token_id(self, token_id, withdraw_partial_percentage=0, burn_nft=False)
It will decrease the liquidity from a specific NFT
and collect the fees earned on it
optional: to completly burn the NFT
Returns: Amount withdrawn, without fees collected
"""
position = self.nonfungible_position_manager.positions(token_id)
deadline = chain.time() + self.deadline
Expand All @@ -169,7 +170,7 @@ def burn_token_id(self, token_id, withdraw_partial_percentage=0, burn_nft=False)
amount1Min *= withdraw_partial_percentage

# requires to remove all liquidity first
self.nonfungible_position_manager.decreaseLiquidity(
tx = self.nonfungible_position_manager.decreaseLiquidity(
(
token_id,
liquidity,
Expand All @@ -178,6 +179,9 @@ def burn_token_id(self, token_id, withdraw_partial_percentage=0, burn_nft=False)
deadline,
)
)
event = tx.events["DecreaseLiquidity"][0]
amount0 = event["amount0"] # Actual amount0 withdrawn from position
amount1 = event["amount1"] # Actual amount1 withdrawn from position

# grab also tokens owned, otherwise cannot burn. ref: https://etherscan.io/address/0xc36442b4a4522e871399cd717abdd847ab11fe88#code#F1#L379
position = self.nonfungible_position_manager.positions(token_id)
Expand All @@ -204,6 +208,8 @@ def burn_token_id(self, token_id, withdraw_partial_percentage=0, burn_nft=False)
# needs to be liq = 0, cleared the pos, otherwise will revert!
self.nonfungible_position_manager.burn(token_id)

return amount0, amount1

def collect_fee(self, token_id):
"""
collect fees for individual token_id
Expand Down
56 changes: 40 additions & 16 deletions scripts/issue/1545/bip_105_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
C = Console()

"""
Active range: https://app.uniswap.org/pools/255188
Active range: https://app.uniswap.org/pools/255188 : 15,780.30 - 31,840.00
Upper ranges (BADGER only):
1. https://app.uniswap.org/pools/198350
2. https://app.uniswap.org/pools/151049
3. https://app.uniswap.org/pools/167046
1. https://app.uniswap.org/pools/198350 : 7,962.9 - 15,780.30
2. https://app.uniswap.org/pools/167046 : 3,994.14 - 7,962.9
3. https://app.uniswap.org/pools/158625 : 1,991.45 - 3,994.14
4. https://app.uniswap.org/pools/151049 : 998.898 - 1,991.45
"""

# Constants: active range, upper ranges and BIP parameter
ACTIVE_RANGE_NFT_ID = 255188
UPPER_RANGE_NFT_IDS = [198350, 151049, 167046]
UPPER_RANGE_NFT_IDS = [198350, 167046, 158625, 151049]
HALF_LIQUIDITY_PCT = 0.5

safe = GreatApeSafe(r.badger_wallets.treasury_vault_multisig)
Expand Down Expand Up @@ -47,12 +48,19 @@ def main():
prev_badger_balance = badger.balanceOf(safe)
prev_wbtc_balance = wbtc.balanceOf(safe)

safe.uni_v3.burn_token_id(ACTIVE_RANGE_NFT_ID, HALF_LIQUIDITY_PCT)
amount_wbtc, amount_badger = safe.uni_v3.burn_token_id(
ACTIVE_RANGE_NFT_ID, HALF_LIQUIDITY_PCT
)
C.print(
f"[green]WBTC fee: {(wbtc.balanceOf(safe) - prev_wbtc_balance - amount_wbtc) / 1e8} from active range withdrawal[/green]"
)
C.print(
f"[green]BADGER fee: {(badger.balanceOf(safe) - prev_badger_balance - amount_badger) / 1e18} from active range withdrawal[/green]"
)

# 2. Buy eBTC with withdrawn WBTC funds
wbtc_sell_amount = wbtc.balanceOf(safe) - prev_wbtc_balance
C.print(f"[green]WBTC to sell for eBTC: {wbtc_sell_amount}[/green]")
ebtc_balance = safe.uni_v3.swap([wbtc, ebtc], wbtc_sell_amount)
C.print(f"[green]WBTC to sell for eBTC: {amount_wbtc}[/green]")
ebtc_balance = safe.uni_v3.swap([wbtc, ebtc], amount_wbtc)

# 3. Pool creation (BADGER/EBTC) and initilization
pool_ebtc_badger_address = safe.uni_v3.factory.createPool(
Expand Down Expand Up @@ -91,18 +99,18 @@ def main():
safe.uni_v3.nonfungible_position_manager, ACTIVE_RANGE_NFT_ID, decimals_diff
)

badger_to_deposit_active_range = (
badger.balanceOf(safe.address) - prev_badger_balance
C.print(
f"[green]BADGER amount to deposit in active range: {amount_badger / 1e18}[/green]"
)
C.print(
f"[green]BADGER amount to deposit in active range: {badger_to_deposit_active_range}[/green]"
f"[green]eBTC amount to deposit in active range: {ebtc_balance / 1e18}[/green]"
)

safe.uni_v3.mint_position(
pool_ebtc_badger_address,
active_range_0,
active_range_1,
badger_to_deposit_active_range,
amount_badger,
ebtc_balance,
)

Expand All @@ -113,18 +121,32 @@ def main():
)

badger_bal_before = badger.balanceOf(safe.address)
safe.uni_v3.burn_token_id(nft_id, HALF_LIQUIDITY_PCT)
wbtc_bal_before = wbtc.balanceOf(safe.address)
amount_wbtc, amount_badger = safe.uni_v3.burn_token_id(
nft_id, HALF_LIQUIDITY_PCT
)
assert amount_wbtc == 0, "WBTC should be 0"
C.print(
f"[green]wBTC fee: {(wbtc.balanceOf(safe.address) - wbtc_bal_before) / 1e8} from upper range withdrawal[/green]"
)
C.print(
f"[green]Badger fee: {(badger.balanceOf(safe.address) - badger_bal_before - amount_badger) / 1e18} from upper range withdrawal[/green]"
)

# NOTE: ensure clean BADGER approval. Force to set back to zero due to its nature
# otherwise may revert in the internal approval of the class
badger.approve(safe.uni_v3.nonfungible_position_manager.address, 0)

# NOTE: deposit the difference only. should be theoretically 100% BADGER nft's
C.print(
f"[green]BADGER amount to deposit in upper range: {amount_badger / 1e18}[/green]"
)

# NOTE: deposit exactly what was obtained from the withdrawal of the upper range, excluding any fees collected
safe.uni_v3.mint_position(
pool_ebtc_badger_address,
range_0,
range_1,
badger.balanceOf(safe.address) - badger_bal_before,
amount_badger,
0, # should be theoretically 0 eBTC
)

Expand All @@ -144,5 +166,7 @@ def _range_prices(position_manager, token_id, decimals_diff):
range_1 = 1 / (BASE ** tick_upper) * 10 ** decimals_diff
C.print(f"[green]range_0: {range_0}[/green]")
C.print(f"[green]range_1: {range_1}\n[/green]")
C.print(f"[green]price0: {1/range_0}[/green]") # To match UniV3 UI
C.print(f"[green]price1: {1/range_1}\n[/green]") # To match UniV3 UI

return range_0, range_1

0 comments on commit 964625a

Please sign in to comment.