wip
This commit is contained in:
parent
981b42eb24
commit
f1729770e3
@ -1 +1 @@
|
||||
[{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"interestRateMode","type":"uint256"},{"internalType":"uint16","name":"referralCode","type":"uint16"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint16","name":"referralCode","type":"uint16"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserAccountData","outputs":[{"internalType":"uint256","name":"totalCollateralETH","type":"uint256"},{"internalType":"uint256","name":"totalDebtETH","type":"uint256"},{"internalType":"uint256","name":"availableBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rateMode","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"repay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
|
||||
[{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"interestRateMode","type":"uint256"},{"internalType":"uint16","name":"referralCode","type":"uint16"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint16","name":"referralCode","type":"uint16"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReserveData","outputs":[{"internalType":"uint256","name":"configuration","type":"uint256"},{"internalType":"uint256","name":"liquidityIndex","type":"uint256"},{"internalType":"uint256","name":"variableBorrowIndex","type":"uint256"},{"internalType":"uint256","name":"currentLiquidityRate","type":"uint256"},{"internalType":"uint256","name":"currentVariableBorrowRate","type":"uint256"},{"internalType":"uint256","name":"currentStableBorrowRate","type":"uint256"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"},{"internalType":"address","name":"aTokenAddress","type":"address"},{"internalType":"address","name":"stableDebtTokenAddress","type":"address"},{"internalType":"address","name":"variableDebtTokenAddress","type":"address"},{"internalType":"address","name":"interestRateStrategyAddress","type":"address"},{"internalType":"uint8","name":"id","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserAccountData","outputs":[{"internalType":"uint256","name":"totalCollateralETH","type":"uint256"},{"internalType":"uint256","name":"totalDebtETH","type":"uint256"},{"internalType":"uint256","name":"availableBorrowsETH","type":"uint256"},{"internalType":"uint256","name":"currentLiquidationThreshold","type":"uint256"},{"internalType":"uint256","name":"ltv","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rateMode","type":"uint256"},{"internalType":"address","name":"onBehalfOf","type":"address"}],"name":"repay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
|
@ -30,7 +30,7 @@ var (
|
||||
|
||||
// LendingPoolMetaData contains all meta data concerning the LendingPool contract.
|
||||
var LendingPoolMetaData = &bind.MetaData{
|
||||
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"interestRateMode\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"referralCode\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"}],\"name\":\"borrow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"referralCode\",\"type\":\"uint16\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getUserAccountData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalCollateralETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalDebtETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableBorrowsETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentLiquidationThreshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ltv\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"healthFactor\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateMode\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"}],\"name\":\"repay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
||||
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"interestRateMode\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"referralCode\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"}],\"name\":\"borrow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"referralCode\",\"type\":\"uint16\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getReserveData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"configuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"liquidityIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"variableBorrowIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentLiquidityRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentVariableBorrowRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentStableBorrowRate\",\"type\":\"uint256\"},{\"internalType\":\"uint40\",\"name\":\"lastUpdateTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"address\",\"name\":\"aTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"stableDebtTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"variableDebtTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"interestRateStrategyAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"id\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getUserAccountData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"totalCollateralETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalDebtETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"availableBorrowsETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentLiquidationThreshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ltv\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"healthFactor\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"rateMode\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"onBehalfOf\",\"type\":\"address\"}],\"name\":\"repay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
||||
}
|
||||
|
||||
// LendingPoolABI is the input ABI used to generate the binding from.
|
||||
@ -179,6 +179,101 @@ func (_LendingPool *LendingPoolTransactorRaw) Transact(opts *bind.TransactOpts,
|
||||
return _LendingPool.Contract.contract.Transact(opts, method, params...)
|
||||
}
|
||||
|
||||
// GetReserveData is a free data retrieval call binding the contract method 0x35ea6a75.
|
||||
//
|
||||
// Solidity: function getReserveData(address asset) view returns(uint256 configuration, uint256 liquidityIndex, uint256 variableBorrowIndex, uint256 currentLiquidityRate, uint256 currentVariableBorrowRate, uint256 currentStableBorrowRate, uint40 lastUpdateTimestamp, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id)
|
||||
func (_LendingPool *LendingPoolCaller) GetReserveData(opts *bind.CallOpts, asset common.Address) (struct {
|
||||
Configuration *big.Int
|
||||
LiquidityIndex *big.Int
|
||||
VariableBorrowIndex *big.Int
|
||||
CurrentLiquidityRate *big.Int
|
||||
CurrentVariableBorrowRate *big.Int
|
||||
CurrentStableBorrowRate *big.Int
|
||||
LastUpdateTimestamp *big.Int
|
||||
ATokenAddress common.Address
|
||||
StableDebtTokenAddress common.Address
|
||||
VariableDebtTokenAddress common.Address
|
||||
InterestRateStrategyAddress common.Address
|
||||
Id uint8
|
||||
}, error) {
|
||||
var out []interface{}
|
||||
err := _LendingPool.contract.Call(opts, &out, "getReserveData", asset)
|
||||
|
||||
outstruct := new(struct {
|
||||
Configuration *big.Int
|
||||
LiquidityIndex *big.Int
|
||||
VariableBorrowIndex *big.Int
|
||||
CurrentLiquidityRate *big.Int
|
||||
CurrentVariableBorrowRate *big.Int
|
||||
CurrentStableBorrowRate *big.Int
|
||||
LastUpdateTimestamp *big.Int
|
||||
ATokenAddress common.Address
|
||||
StableDebtTokenAddress common.Address
|
||||
VariableDebtTokenAddress common.Address
|
||||
InterestRateStrategyAddress common.Address
|
||||
Id uint8
|
||||
})
|
||||
if err != nil {
|
||||
return *outstruct, err
|
||||
}
|
||||
|
||||
outstruct.Configuration = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
|
||||
outstruct.LiquidityIndex = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
|
||||
outstruct.VariableBorrowIndex = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
|
||||
outstruct.CurrentLiquidityRate = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
|
||||
outstruct.CurrentVariableBorrowRate = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
|
||||
outstruct.CurrentStableBorrowRate = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int)
|
||||
outstruct.LastUpdateTimestamp = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int)
|
||||
outstruct.ATokenAddress = *abi.ConvertType(out[7], new(common.Address)).(*common.Address)
|
||||
outstruct.StableDebtTokenAddress = *abi.ConvertType(out[8], new(common.Address)).(*common.Address)
|
||||
outstruct.VariableDebtTokenAddress = *abi.ConvertType(out[9], new(common.Address)).(*common.Address)
|
||||
outstruct.InterestRateStrategyAddress = *abi.ConvertType(out[10], new(common.Address)).(*common.Address)
|
||||
outstruct.Id = *abi.ConvertType(out[11], new(uint8)).(*uint8)
|
||||
|
||||
return *outstruct, err
|
||||
|
||||
}
|
||||
|
||||
// GetReserveData is a free data retrieval call binding the contract method 0x35ea6a75.
|
||||
//
|
||||
// Solidity: function getReserveData(address asset) view returns(uint256 configuration, uint256 liquidityIndex, uint256 variableBorrowIndex, uint256 currentLiquidityRate, uint256 currentVariableBorrowRate, uint256 currentStableBorrowRate, uint40 lastUpdateTimestamp, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id)
|
||||
func (_LendingPool *LendingPoolSession) GetReserveData(asset common.Address) (struct {
|
||||
Configuration *big.Int
|
||||
LiquidityIndex *big.Int
|
||||
VariableBorrowIndex *big.Int
|
||||
CurrentLiquidityRate *big.Int
|
||||
CurrentVariableBorrowRate *big.Int
|
||||
CurrentStableBorrowRate *big.Int
|
||||
LastUpdateTimestamp *big.Int
|
||||
ATokenAddress common.Address
|
||||
StableDebtTokenAddress common.Address
|
||||
VariableDebtTokenAddress common.Address
|
||||
InterestRateStrategyAddress common.Address
|
||||
Id uint8
|
||||
}, error) {
|
||||
return _LendingPool.Contract.GetReserveData(&_LendingPool.CallOpts, asset)
|
||||
}
|
||||
|
||||
// GetReserveData is a free data retrieval call binding the contract method 0x35ea6a75.
|
||||
//
|
||||
// Solidity: function getReserveData(address asset) view returns(uint256 configuration, uint256 liquidityIndex, uint256 variableBorrowIndex, uint256 currentLiquidityRate, uint256 currentVariableBorrowRate, uint256 currentStableBorrowRate, uint40 lastUpdateTimestamp, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id)
|
||||
func (_LendingPool *LendingPoolCallerSession) GetReserveData(asset common.Address) (struct {
|
||||
Configuration *big.Int
|
||||
LiquidityIndex *big.Int
|
||||
VariableBorrowIndex *big.Int
|
||||
CurrentLiquidityRate *big.Int
|
||||
CurrentVariableBorrowRate *big.Int
|
||||
CurrentStableBorrowRate *big.Int
|
||||
LastUpdateTimestamp *big.Int
|
||||
ATokenAddress common.Address
|
||||
StableDebtTokenAddress common.Address
|
||||
VariableDebtTokenAddress common.Address
|
||||
InterestRateStrategyAddress common.Address
|
||||
Id uint8
|
||||
}, error) {
|
||||
return _LendingPool.Contract.GetReserveData(&_LendingPool.CallOpts, asset)
|
||||
}
|
||||
|
||||
// GetUserAccountData is a free data retrieval call binding the contract method 0xbf92857c.
|
||||
//
|
||||
// Solidity: function getUserAccountData(address user) view returns(uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)
|
||||
|
@ -18,4 +18,19 @@ interface ILendingPool {
|
||||
uint256 ltv,
|
||||
uint256 healthFactor
|
||||
);
|
||||
|
||||
function getReserveData(address asset) external view returns (
|
||||
uint256 configuration,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex,
|
||||
uint256 currentLiquidityRate,
|
||||
uint256 currentVariableBorrowRate,
|
||||
uint256 currentStableBorrowRate,
|
||||
uint40 lastUpdateTimestamp,
|
||||
address aTokenAddress,
|
||||
address stableDebtTokenAddress,
|
||||
address variableDebtTokenAddress,
|
||||
address interestRateStrategyAddress,
|
||||
uint8 id
|
||||
);
|
||||
}
|
@ -3,6 +3,7 @@ package aave
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/aave/contracts"
|
||||
@ -13,6 +14,10 @@ import (
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
const (
|
||||
SECONDSPERYEAR = 31536000
|
||||
)
|
||||
|
||||
type LendingPool struct {
|
||||
client evm.Client
|
||||
contract *contracts.LendingPool
|
||||
@ -61,29 +66,56 @@ func (lp *LendingPool) UserAccountDataForAddress(address common.Address) (UserAc
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (lp *LendingPool) Borrow(ctx context.Context, asset common.Address, amount decimal.Decimal) (evm.Transaction, error) {
|
||||
token, err := lp.client.TokenService().TokenByAddress(asset)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting token")
|
||||
}
|
||||
return lp.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return lp.contract.Borrow(opts.TransactOpts, asset, token.ValueToBigInt(amount), big.NewInt(2), 0, lp.client.PublicAddress())
|
||||
})
|
||||
type ReserveData struct {
|
||||
LiquidityIndex decimal.Decimal
|
||||
VariableBorrowIndex decimal.Decimal
|
||||
CurrentLiquidityRate decimal.Decimal
|
||||
CurrentVariableBorrowRate decimal.Decimal
|
||||
CurrentStableBorrowRate decimal.Decimal
|
||||
LastUpdateTimestamp time.Time
|
||||
ATokenAddress common.Address
|
||||
StableDebtTokenAddress common.Address
|
||||
VariableDebtTokenAddress common.Address
|
||||
InterestRateStrategyAddress common.Address
|
||||
Id uint8
|
||||
}
|
||||
|
||||
func (lp *LendingPool) Repay(ctx context.Context, asset common.Address, amount decimal.Decimal) (evm.Transaction, error) {
|
||||
token, err := lp.client.TokenService().TokenByAddress(asset)
|
||||
func (lp *LendingPool) ReserveData(asset evm.Token) (ReserveData, error) {
|
||||
rd, err := lp.contract.GetReserveData(&bind.CallOpts{}, asset.Address())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting token")
|
||||
return ReserveData{}, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
balance, err := token.Balance()
|
||||
res := ReserveData{
|
||||
LiquidityIndex: decimal.NewFromBigInt(rd.LiquidityIndex, -27),
|
||||
VariableBorrowIndex: decimal.NewFromBigInt(rd.VariableBorrowIndex, -27),
|
||||
CurrentLiquidityRate: decimal.NewFromBigInt(rd.CurrentLiquidityRate, -27),
|
||||
CurrentVariableBorrowRate: decimal.NewFromBigInt(rd.CurrentVariableBorrowRate, -27),
|
||||
CurrentStableBorrowRate: decimal.NewFromBigInt(rd.CurrentStableBorrowRate, -27),
|
||||
LastUpdateTimestamp: time.Unix(rd.LastUpdateTimestamp.Int64(), 0),
|
||||
ATokenAddress: rd.ATokenAddress,
|
||||
StableDebtTokenAddress: rd.StableDebtTokenAddress,
|
||||
VariableDebtTokenAddress: rd.VariableDebtTokenAddress,
|
||||
InterestRateStrategyAddress: rd.InterestRateStrategyAddress,
|
||||
Id: rd.Id,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (lp *LendingPool) Borrow(ctx context.Context, asset evm.Token, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
return lp.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return lp.contract.Borrow(opts.TransactOpts, asset.Address(), asset.ValueToBigInt(amount), big.NewInt(2), 0, lp.client.PublicAddress())
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func (lp *LendingPool) Repay(ctx context.Context, asset evm.Token, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
balance, err := asset.Balance()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting token balance")
|
||||
}
|
||||
if balance.LessThan(amount) {
|
||||
return nil, errors.Wrapf(err, "balance of %s insufficient. need %s have %s", token.Symbol(), amount, balance)
|
||||
return nil, errors.Wrapf(err, "balance of %s insufficient. need %s have %s", asset.Symbol(), amount, balance)
|
||||
}
|
||||
return lp.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return lp.contract.Repay(opts.TransactOpts, asset, token.ValueToBigInt(amount), big.NewInt(2), lp.client.PublicAddress())
|
||||
})
|
||||
return lp.contract.Repay(opts.TransactOpts, asset.Address(), asset.ValueToBigInt(amount), big.NewInt(2), lp.client.PublicAddress())
|
||||
}, opts...)
|
||||
}
|
||||
|
@ -74,5 +74,6 @@ func NewTokenMapper() evm.TokenMapper {
|
||||
tm.AddAlias("ETH", "WETH.e")
|
||||
tm.AddAlias("BTC", "WBTC.e")
|
||||
tm.AddAlias("USDC", "USDC.e")
|
||||
tm.AddAlias("DAI", "DAI.e")
|
||||
return tm
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package beefy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/beefy/contracts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
@ -13,6 +16,8 @@ type VaultV6 struct {
|
||||
evm.Token
|
||||
client evm.Client
|
||||
contract *contracts.VaultV6
|
||||
|
||||
Underlying evm.Token
|
||||
}
|
||||
|
||||
func NewVaultV6(client evm.Client, address common.Address) (*VaultV6, error) {
|
||||
@ -24,11 +29,20 @@ func NewVaultV6(client evm.Client, address common.Address) (*VaultV6, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init token contract")
|
||||
}
|
||||
wantaddress, err := contract.Want(&bind.CallOpts{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting underlying token address")
|
||||
}
|
||||
want, err := client.TokenService().TokenByAddress(wantaddress)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init underlying token contract")
|
||||
}
|
||||
|
||||
return &VaultV6{
|
||||
client: client,
|
||||
contract: contract,
|
||||
Token: token,
|
||||
client: client,
|
||||
contract: contract,
|
||||
Token: token,
|
||||
Underlying: want,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -39,3 +53,15 @@ func (v *VaultV6) PricePerFullShare() (decimal.Decimal, error) {
|
||||
}
|
||||
return v.ValueFromBigInt(ppfs), nil
|
||||
}
|
||||
|
||||
func (v *VaultV6) Deposit(ctx context.Context, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
return v.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return v.contract.Deposit(opts.TransactOpts, v.Underlying.ValueToBigInt(amount))
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func (v *VaultV6) Withdraw(ctx context.Context, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
return v.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return v.contract.Withdraw(opts.TransactOpts, v.ValueToBigInt(amount))
|
||||
}, opts...)
|
||||
}
|
||||
|
113
curve/Pool.go
113
curve/Pool.go
@ -1,6 +1,11 @@
|
||||
package curve
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/curve/contracts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
@ -31,11 +36,35 @@ func NewPool(client evm.Client, address common.Address) (*Pool, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting lp token")
|
||||
}
|
||||
return &Pool{
|
||||
p := &Pool{
|
||||
client: client,
|
||||
contract: contract,
|
||||
lptoken: lptoken,
|
||||
}, nil
|
||||
}
|
||||
tokens, err := p.getTokens()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting underlying tokens")
|
||||
}
|
||||
p.tokens = tokens
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *Pool) getTokens() ([]evm.Token, error) {
|
||||
var res []evm.Token
|
||||
var index int64
|
||||
for {
|
||||
t, err := p.contract.UnderlyingCoins(&bind.CallOpts{}, big.NewInt(index))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
token, err := p.client.TokenService().TokenByAddress(t)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "getting token %s", t)
|
||||
}
|
||||
res = append(res, token)
|
||||
index++
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (p *Pool) VirtualPrice() (decimal.Decimal, error) {
|
||||
@ -47,4 +76,82 @@ func (p *Pool) VirtualPrice() (decimal.Decimal, error) {
|
||||
return decimal.NewFromBigInt(price, -18), nil
|
||||
}
|
||||
|
||||
//func (p *Pool) CalculateTokenAmount(amounts []decimal.Decimal)
|
||||
func (p *Pool) CalculateTokenAmountForOneUnderlying(token evm.Token, amount decimal.Decimal, isdeposit bool) (decimal.Decimal, error) {
|
||||
tokenindex, err := p.getTokenIndex(token)
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "getting token index")
|
||||
}
|
||||
var amounts [3]*big.Int
|
||||
for i, _ := range p.tokens {
|
||||
if i == tokenindex {
|
||||
amounts[i] = token.ValueToBigInt(amount)
|
||||
} else {
|
||||
amounts[i] = big.NewInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
raw, err := p.contract.CalcTokenAmount(&bind.CallOpts{}, amounts, isdeposit)
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
return p.lptoken.ValueFromBigInt(raw), nil
|
||||
}
|
||||
|
||||
func (p *Pool) CalculateWithdrawOneCoin(token evm.Token, amount decimal.Decimal) (decimal.Decimal, error) {
|
||||
tokenindex, err := p.getTokenIndex(token)
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "getting token index")
|
||||
}
|
||||
raw, err := p.contract.CalcWithdrawOneCoin(&bind.CallOpts{}, p.lptoken.ValueToBigInt(amount), big.NewInt(int64(tokenindex)))
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
return token.ValueFromBigInt(raw), nil
|
||||
}
|
||||
|
||||
func (p *Pool) getTokenIndex(token evm.Token) (int, error) {
|
||||
tokenindex := -1
|
||||
for i, t := range p.tokens {
|
||||
if t.Address() == token.Address() {
|
||||
tokenindex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if tokenindex == -1 {
|
||||
return -1, errors.Errorf("token %s not found in pool", token.Symbol())
|
||||
}
|
||||
return tokenindex, nil
|
||||
}
|
||||
|
||||
func (p *Pool) AddLiquidity(ctx context.Context, token evm.Token, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
tokenindex, err := p.getTokenIndex(token)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting token index")
|
||||
}
|
||||
amounts := [3]*big.Int{big.NewInt(0), big.NewInt(0), big.NewInt(0)}
|
||||
amounts[tokenindex] = token.ValueToBigInt(amount)
|
||||
minMintAmount, err := p.CalculateTokenAmountForOneUnderlying(token, amount, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting mint amount")
|
||||
}
|
||||
minMintAmount = minMintAmount.Sub(minMintAmount.Mul(decimal.NewFromFloat(0.01))).Round(int32(p.lptoken.Decimals()))
|
||||
return p.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return p.contract.AddLiquidity0(opts.TransactOpts, amounts, p.lptoken.ValueToBigInt(minMintAmount), true)
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func (p *Pool) RemoveLiquidity(ctx context.Context, token evm.Token, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
|
||||
tokenindex, err := p.getTokenIndex(token)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting token index")
|
||||
}
|
||||
minamount, err := p.CalculateWithdrawOneCoin(token, amount)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "calculate withdraw one coin")
|
||||
}
|
||||
minamount = minamount.Sub(minamount.Mul(decimal.NewFromFloat(0.002))).Round(int32(token.Decimals()))
|
||||
|
||||
return p.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
|
||||
return p.contract.RemoveLiquidityOneCoin0(opts.TransactOpts, p.lptoken.ValueToBigInt(amount), big.NewInt(int64(tokenindex)), token.ValueToBigInt(minamount), true)
|
||||
}, opts...)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user