Skip to content

Commit 8039278

Browse files
committed
feat: DepositAndStakeZapNgPoolsOnly
1 parent 6892c32 commit 8039278

File tree

2 files changed

+110
-212
lines changed

2 files changed

+110
-212
lines changed

contracts/DepositAndStakeZap0.3.10.vy

-212
This file was deleted.
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# @version 0.3.10
2+
# pragma evm-version paris
3+
4+
"""
5+
@title CurveDeposit&StakeZap
6+
@author Curve.Fi
7+
@license Copyright (c) Curve.Fi, 2020-2024 - all rights reserved
8+
@notice A zap to add liquidity to pool and deposit into gauge in one transaction
9+
"""
10+
11+
version: public(constant(String[8])) = "1.0.0"
12+
13+
14+
MAX_COINS: constant(uint256) = 9
15+
16+
# External Contracts
17+
from vyper.interfaces import ERC20
18+
19+
interface Pool2:
20+
def add_liquidity(amounts: uint256[2], min_mint_amount: uint256): nonpayable
21+
22+
interface Pool3:
23+
def add_liquidity(amounts: uint256[3], min_mint_amount: uint256): nonpayable
24+
25+
interface PoolStableNg:
26+
def add_liquidity(_amounts: DynArray[uint256, MAX_COINS], _min_mint_amount: uint256): nonpayable
27+
28+
interface MetaZap:
29+
def add_liquidity(pool: address, _amounts: DynArray[uint256, MAX_COINS], _min_mint_amount: uint256): nonpayable
30+
31+
interface Gauge:
32+
def deposit(lp_token_amount: uint256, addr: address): nonpayable
33+
34+
@external
35+
@nonreentrant('lock')
36+
def deposit_and_stake(
37+
deposit: address,
38+
lp_token: address,
39+
gauge: address,
40+
n_coins: uint256,
41+
coins: DynArray[address, MAX_COINS],
42+
amounts: DynArray[uint256, MAX_COINS],
43+
min_mint_amount: uint256,
44+
use_dynarray: bool,
45+
pool: address = empty(address),
46+
) -> uint256:
47+
"""
48+
@notice Deposit coins into pool and stake obtained LP tokens into gauge.
49+
Zap address should be passed to `deposit` arg in case of meta-pool deposit with underlying coins.
50+
@param deposit Zap address for meta-pool deposit with underlying coins, pool address for other cases.
51+
@param lp_token The address of LP token
52+
@param gauge The address of gauge
53+
@param n_coins The number of tokens (underlying or wrapped for meta-pools)
54+
@param coins List of addresses of coins (underlying or wrapped for meta-pools)
55+
@param amounts List of amounts of coins to deposit (underlying or wrapped for meta-pools)
56+
@param min_mint_amount Minimum amount of LP tokens to mint from the deposit
57+
@param use_dynarray True - plain stable, meta stable with underlying coins
58+
False - twocrypto, tricrypto, meta stable with wrapped coins
59+
@param pool The address of meta-pool in case of deposit with underlying coins
60+
@return Amount of LP tokens staked into gauge
61+
"""
62+
assert n_coins >= 2, 'n_coins must be >=2'
63+
assert n_coins <= MAX_COINS, 'n_coins must be <=MAX_COINS'
64+
65+
# Ensure allowance for swap or zap
66+
for i in range(MAX_COINS):
67+
if i == n_coins:
68+
break
69+
if amounts[i] == 0 or ERC20(coins[i]).allowance(self, deposit) > 0:
70+
continue
71+
ERC20(coins[i]).approve(deposit, max_value(uint256), default_return_value=True)
72+
73+
# Ensure allowance for gauge
74+
if ERC20(lp_token).allowance(self, gauge) == 0:
75+
ERC20(lp_token).approve(gauge, max_value(uint256))
76+
77+
# Transfer coins from owner
78+
for i in range(MAX_COINS):
79+
if i == n_coins:
80+
break
81+
82+
if amounts[i] > 0:
83+
assert ERC20(coins[i]).transferFrom(msg.sender, self, amounts[i], default_return_value=True)
84+
85+
# Deposit into pool
86+
if pool != empty(address): # meta-pool deposit with underlying coins, deposit is zap here
87+
MetaZap(deposit).add_liquidity(pool, amounts, min_mint_amount)
88+
elif use_dynarray: # plain stable pool
89+
PoolStableNg(deposit).add_liquidity(amounts, min_mint_amount)
90+
else:
91+
if n_coins == 2: # twocrypto or meta-pool deposit with wrapped coins
92+
Pool2(deposit).add_liquidity([amounts[0], amounts[1]], min_mint_amount)
93+
elif n_coins == 3: # tricrypto
94+
Pool3(deposit).add_liquidity([amounts[0], amounts[1], amounts[2]], min_mint_amount)
95+
else:
96+
raise "Wrong arguments"
97+
98+
# Stake into gauge
99+
lp_token_amount: uint256 = ERC20(lp_token).balanceOf(self)
100+
assert lp_token_amount > 0 # dev: swap-token mismatch
101+
102+
Gauge(gauge).deposit(lp_token_amount, msg.sender)
103+
104+
return lp_token_amount
105+
106+
107+
@payable
108+
@external
109+
def __default__():
110+
pass

0 commit comments

Comments
 (0)