curve + aave + beefy
This commit is contained in:
parent
916759a907
commit
73bb337e4b
21
aave/contracts/dataprovider.sol
Normal file
21
aave/contracts/dataprovider.sol
Normal file
@ -0,0 +1,21 @@
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
interface IDataProvider {
|
||||
function getReserveTokensAddresses(address asset) external view returns (
|
||||
address aTokenAddress,
|
||||
address stableDebtTokenAddress,
|
||||
address variableDebtTokenAddress
|
||||
);
|
||||
|
||||
function getUserReserveData(address asset, address user) external view returns (
|
||||
uint256 currentATokenBalance,
|
||||
uint256 currentStableDebt,
|
||||
uint256 currentVariableDebt,
|
||||
uint256 principalStableDebt,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 liquidityRate,
|
||||
uint40 stableRateLastUpdated,
|
||||
bool usageAsCollateralEnabled
|
||||
);
|
||||
}
|
6
aave/contracts/incentivescontroller.sol
Normal file
6
aave/contracts/incentivescontroller.sol
Normal file
@ -0,0 +1,6 @@
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
interface IIncentivesController {
|
||||
function claimRewards(address[] calldata assets, uint256 amount, address to) external returns (uint256);
|
||||
function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256);
|
||||
}
|
21
aave/contracts/lendingpool.sol
Normal file
21
aave/contracts/lendingpool.sol
Normal file
@ -0,0 +1,21 @@
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
interface ILendingPool {
|
||||
|
||||
function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
|
||||
|
||||
function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external;
|
||||
|
||||
function repay(address asset, uint256 amount, uint256 rateMode, address onBehalfOf) external returns (uint256);
|
||||
|
||||
function withdraw(address asset, uint256 amount, address to) external returns (uint256);
|
||||
|
||||
function getUserAccountData(address user) external view returns (
|
||||
uint256 totalCollateralETH,
|
||||
uint256 totalDebtETH,
|
||||
uint256 availableBorrowsETH,
|
||||
uint256 currentLiquidationThreshold,
|
||||
uint256 ltv,
|
||||
uint256 healthFactor
|
||||
);
|
||||
}
|
62
aave/dataprovider.go
Normal file
62
aave/dataprovider.go
Normal file
@ -0,0 +1,62 @@
|
||||
package aave
|
||||
|
||||
import (
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/aave/contracts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type DataProvider struct {
|
||||
client evm.Client
|
||||
contract *contracts.DataProvider
|
||||
}
|
||||
|
||||
func NewDataProvider(client evm.Client, address common.Address) (*DataProvider, error) {
|
||||
contract, err := contracts.NewDataProvider(address, client)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init contract")
|
||||
}
|
||||
|
||||
return &DataProvider{
|
||||
client: client,
|
||||
contract: contract,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type UserReserveData struct {
|
||||
CurrentATokenBalance decimal.Decimal
|
||||
CurrentStableDebt decimal.Decimal
|
||||
CurrentVariableDebt decimal.Decimal
|
||||
PrincipalStableDebt decimal.Decimal
|
||||
ScaledVariableDebt decimal.Decimal
|
||||
StableBorrowRate decimal.Decimal
|
||||
LiquidityRate decimal.Decimal
|
||||
StableRateLastUpdated decimal.Decimal
|
||||
UsageAsCollateralEnabled bool
|
||||
}
|
||||
|
||||
func (d *DataProvider) UserReserveData(asset common.Address, address common.Address) (UserReserveData, error) {
|
||||
token, err := d.client.TokenService().TokenByAddress(asset)
|
||||
if err != nil {
|
||||
return UserReserveData{}, errors.Wrap(err, "get token")
|
||||
}
|
||||
rd, err := d.contract.GetUserReserveData(&bind.CallOpts{}, asset, address)
|
||||
if err != nil {
|
||||
return UserReserveData{}, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
|
||||
return UserReserveData{
|
||||
CurrentATokenBalance: token.ValueFromBigInt(rd.CurrentATokenBalance),
|
||||
CurrentStableDebt: token.ValueFromBigInt(rd.CurrentStableDebt),
|
||||
CurrentVariableDebt: token.ValueFromBigInt(rd.CurrentVariableDebt),
|
||||
PrincipalStableDebt: token.ValueFromBigInt(rd.PrincipalStableDebt),
|
||||
ScaledVariableDebt: token.ValueFromBigInt(rd.ScaledVariableDebt),
|
||||
StableBorrowRate: token.ValueFromBigInt(rd.StableBorrowRate),
|
||||
LiquidityRate: token.ValueFromBigInt(rd.LiquidityRate),
|
||||
StableRateLastUpdated: token.ValueFromBigInt(rd.StableRateLastUpdated),
|
||||
UsageAsCollateralEnabled: rd.UsageAsCollateralEnabled,
|
||||
}, nil
|
||||
}
|
89
aave/lendingpool.go
Normal file
89
aave/lendingpool.go
Normal file
@ -0,0 +1,89 @@
|
||||
package aave
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/aave/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"
|
||||
)
|
||||
|
||||
type LendingPool struct {
|
||||
client evm.Client
|
||||
contract *contracts.LendingPool
|
||||
}
|
||||
|
||||
func NewLendingPool(client evm.Client, address common.Address) (*LendingPool, error) {
|
||||
contract, err := contracts.NewLendingPool(address, client)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init contract")
|
||||
}
|
||||
|
||||
return &LendingPool{
|
||||
client: client,
|
||||
contract: contract,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type UserAccountData struct {
|
||||
TotalCollateralETH decimal.Decimal
|
||||
TotalDebtETH decimal.Decimal
|
||||
AvailableBorrowsETH decimal.Decimal
|
||||
CurrentLiquidationThreshold decimal.Decimal
|
||||
CurrentLtv decimal.Decimal
|
||||
MaxLtv decimal.Decimal
|
||||
HealthFactor decimal.Decimal
|
||||
}
|
||||
|
||||
func (uad UserAccountData) BorrowAmountToLtv(ltv decimal.Decimal) decimal.Decimal {
|
||||
return uad.TotalCollateralETH.Mul(ltv).Div(decimal.NewFromInt(100)).Sub(uad.TotalDebtETH)
|
||||
}
|
||||
|
||||
func (lp *LendingPool) UserAccountDataForAddress(address common.Address) (UserAccountData, error) {
|
||||
uad, err := lp.contract.GetUserAccountData(&bind.CallOpts{}, address)
|
||||
if err != nil {
|
||||
return UserAccountData{}, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
res := UserAccountData{
|
||||
TotalCollateralETH: decimal.NewFromBigInt(uad.TotalCollateralETH, -8),
|
||||
TotalDebtETH: decimal.NewFromBigInt(uad.TotalDebtETH, -8),
|
||||
AvailableBorrowsETH: decimal.NewFromBigInt(uad.AvailableBorrowsETH, -8),
|
||||
CurrentLiquidationThreshold: decimal.NewFromBigInt(uad.CurrentLiquidationThreshold, -2),
|
||||
MaxLtv: decimal.NewFromBigInt(uad.Ltv, -2),
|
||||
HealthFactor: decimal.NewFromBigInt(uad.HealthFactor, -18),
|
||||
}
|
||||
res.CurrentLtv = res.TotalDebtETH.Div(res.TotalCollateralETH).Mul(decimal.NewFromInt(100))
|
||||
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())
|
||||
})
|
||||
}
|
||||
|
||||
func (lp *LendingPool) Repay(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")
|
||||
}
|
||||
balance, err := token.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 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())
|
||||
})
|
||||
}
|
@ -62,6 +62,7 @@ var tokens = map[string]string{
|
||||
"xJOE": "0x57319d41f71e81f3c65f2a47ca4e001ebafd4f33",
|
||||
"WETH.e": "0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab",
|
||||
"WBTC.e": "0x50b7545627a5162F82A992c33b87aDc75187B218",
|
||||
"USDC.e": "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
|
||||
}
|
||||
|
||||
func NewTokenMapper() evm.TokenMapper {
|
||||
@ -72,5 +73,6 @@ func NewTokenMapper() evm.TokenMapper {
|
||||
|
||||
tm.AddAlias("ETH", "WETH.e")
|
||||
tm.AddAlias("BTC", "WBTC.e")
|
||||
tm.AddAlias("USDC", "USDC.e")
|
||||
return tm
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package beefy
|
||||
import (
|
||||
"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/pkg/errors"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type VaultV6 struct {
|
||||
@ -29,3 +31,11 @@ func NewVaultV6(client evm.Client, address common.Address) (*VaultV6, error) {
|
||||
Token: token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *VaultV6) PricePerFullShare() (decimal.Decimal, error) {
|
||||
ppfs, err := v.contract.GetPricePerFullShare(&bind.CallOpts{})
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
return v.ValueFromBigInt(ppfs), nil
|
||||
}
|
||||
|
50
curve/Pool.go
Normal file
50
curve/Pool.go
Normal file
@ -0,0 +1,50 @@
|
||||
package curve
|
||||
|
||||
import (
|
||||
"git.lehouerou.net/laurent/evm"
|
||||
"git.lehouerou.net/laurent/evm/curve/contracts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type Pool struct {
|
||||
client evm.Client
|
||||
contract *contracts.Pool
|
||||
|
||||
lptoken evm.Token
|
||||
tokens []evm.Token
|
||||
}
|
||||
|
||||
func NewPool(client evm.Client, address common.Address) (*Pool, error) {
|
||||
contract, err := contracts.NewPool(address, client)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "init contract")
|
||||
}
|
||||
|
||||
lptokenaddress, err := contract.LpToken(&bind.CallOpts{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting lp token address")
|
||||
}
|
||||
lptoken, err := client.TokenService().TokenByAddress(lptokenaddress)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting lp token")
|
||||
}
|
||||
return &Pool{
|
||||
client: client,
|
||||
contract: contract,
|
||||
lptoken: lptoken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Pool) VirtualPrice() (decimal.Decimal, error) {
|
||||
price, err := p.contract.GetVirtualPrice(&bind.CallOpts{})
|
||||
if err != nil {
|
||||
return decimal.Zero, errors.Wrap(err, "calling contract")
|
||||
}
|
||||
|
||||
return decimal.NewFromBigInt(price, -18), nil
|
||||
}
|
||||
|
||||
//func (p *Pool) CalculateTokenAmount(amounts []decimal.Decimal)
|
1
curve/contracts/pool.abi
Normal file
1
curve/contracts/pool.abi
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user