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",
|
"xJOE": "0x57319d41f71e81f3c65f2a47ca4e001ebafd4f33",
|
||||||
"WETH.e": "0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab",
|
"WETH.e": "0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab",
|
||||||
"WBTC.e": "0x50b7545627a5162F82A992c33b87aDc75187B218",
|
"WBTC.e": "0x50b7545627a5162F82A992c33b87aDc75187B218",
|
||||||
|
"USDC.e": "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTokenMapper() evm.TokenMapper {
|
func NewTokenMapper() evm.TokenMapper {
|
||||||
@ -72,5 +73,6 @@ func NewTokenMapper() evm.TokenMapper {
|
|||||||
|
|
||||||
tm.AddAlias("ETH", "WETH.e")
|
tm.AddAlias("ETH", "WETH.e")
|
||||||
tm.AddAlias("BTC", "WBTC.e")
|
tm.AddAlias("BTC", "WBTC.e")
|
||||||
|
tm.AddAlias("USDC", "USDC.e")
|
||||||
return tm
|
return tm
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package beefy
|
|||||||
import (
|
import (
|
||||||
"git.lehouerou.net/laurent/evm"
|
"git.lehouerou.net/laurent/evm"
|
||||||
"git.lehouerou.net/laurent/evm/beefy/contracts"
|
"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/common"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VaultV6 struct {
|
type VaultV6 struct {
|
||||||
@ -29,3 +31,11 @@ func NewVaultV6(client evm.Client, address common.Address) (*VaultV6, error) {
|
|||||||
Token: token,
|
Token: token,
|
||||||
}, nil
|
}, 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