diff --git a/aave/contracts/dataprovider.sol b/aave/contracts/dataprovider.sol new file mode 100644 index 0000000..203ad28 --- /dev/null +++ b/aave/contracts/dataprovider.sol @@ -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 + ); +} \ No newline at end of file diff --git a/aave/contracts/incentivescontroller.sol b/aave/contracts/incentivescontroller.sol new file mode 100644 index 0000000..afebdfc --- /dev/null +++ b/aave/contracts/incentivescontroller.sol @@ -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); +} \ No newline at end of file diff --git a/aave/contracts/lendingpool.sol b/aave/contracts/lendingpool.sol new file mode 100644 index 0000000..42fd8f8 --- /dev/null +++ b/aave/contracts/lendingpool.sol @@ -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 + ); +} \ No newline at end of file diff --git a/aave/dataprovider.go b/aave/dataprovider.go new file mode 100644 index 0000000..2a8764a --- /dev/null +++ b/aave/dataprovider.go @@ -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 +} diff --git a/aave/lendingpool.go b/aave/lendingpool.go new file mode 100644 index 0000000..4468550 --- /dev/null +++ b/aave/lendingpool.go @@ -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()) + }) +} diff --git a/avalanche/tokenmapper.go b/avalanche/tokenmapper.go index 44ec3c9..9a54a6f 100644 --- a/avalanche/tokenmapper.go +++ b/avalanche/tokenmapper.go @@ -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 } diff --git a/beefy/vaultv6.go b/beefy/vaultv6.go index 365f4b9..1a5eab4 100644 --- a/beefy/vaultv6.go +++ b/beefy/vaultv6.go @@ -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 +} diff --git a/curve/Pool.go b/curve/Pool.go new file mode 100644 index 0000000..ddb53e5 --- /dev/null +++ b/curve/Pool.go @@ -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) diff --git a/curve/contracts/pool.abi b/curve/contracts/pool.abi new file mode 100644 index 0000000..60c0c9a --- /dev/null +++ b/curve/contracts/pool.abi @@ -0,0 +1 @@ +[{"name":"TokenExchange","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchangeUnderlying","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amount","type":"uint256","indexed":false},{"name":"coin_amount","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitNewAdmin","inputs":[{"name":"deadline","type":"uint256","indexed":true},{"name":"admin","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"NewAdmin","inputs":[{"name":"admin","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"CommitNewFee","inputs":[{"name":"deadline","type":"uint256","indexed":true},{"name":"fee","type":"uint256","indexed":false},{"name":"admin_fee","type":"uint256","indexed":false},{"name":"offpeg_fee_multiplier","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewFee","inputs":[{"name":"fee","type":"uint256","indexed":false},{"name":"admin_fee","type":"uint256","indexed":false},{"name":"offpeg_fee_multiplier","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RampA","inputs":[{"name":"old_A","type":"uint256","indexed":false},{"name":"new_A","type":"uint256","indexed":false},{"name":"initial_time","type":"uint256","indexed":false},{"name":"future_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"StopRampA","inputs":[{"name":"A","type":"uint256","indexed":false},{"name":"t","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_coins","type":"address[3]"},{"name":"_underlying_coins","type":"address[3]"},{"name":"_pool_token","type":"address"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_admin_fee","type":"uint256"},{"name":"_offpeg_fee_multiplier","type":"uint256"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10374},{"stateMutability":"view","type":"function","name":"A_precise","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10336},{"stateMutability":"view","type":"function","name":"dynamic_fee","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"}],"outputs":[{"name":"","type":"uint256"}],"gas":21857},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":7230},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2701683},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"is_deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}],"gas":5367778},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_min_mint_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_min_mint_amount","type":"uint256"},{"name":"_use_underlying","type":"bool"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"get_dy","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":6288606},{"stateMutability":"view","type":"function","name":"get_dy_underlying","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":6288636},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"},{"name":"min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":6464164},{"stateMutability":"nonpayable","type":"function","name":"exchange_underlying","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"},{"name":"min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":6483014},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[3]"}],"outputs":[{"name":"","type":"uint256[3]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[3]"},{"name":"_use_underlying","type":"bool"}],"outputs":[{"name":"","type":"uint256[3]"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_max_burn_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_max_burn_amount","type":"uint256"},{"name":"_use_underlying","type":"bool"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_token_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}],"gas":4490262},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_token_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_token_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_amount","type":"uint256"},{"name":"_use_underlying","type":"bool"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[],"gas":159459},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[],"gas":154920},{"stateMutability":"nonpayable","type":"function","name":"commit_new_fee","inputs":[{"name":"new_fee","type":"uint256"},{"name":"new_admin_fee","type":"uint256"},{"name":"new_offpeg_fee_multiplier","type":"uint256"}],"outputs":[],"gas":148809},{"stateMutability":"nonpayable","type":"function","name":"apply_new_fee","inputs":[],"outputs":[],"gas":141271},{"stateMutability":"nonpayable","type":"function","name":"revert_new_parameters","inputs":[],"outputs":[],"gas":23012},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_ownership","inputs":[{"name":"_owner","type":"address"}],"outputs":[],"gas":77050},{"stateMutability":"nonpayable","type":"function","name":"apply_transfer_ownership","inputs":[],"outputs":[],"gas":65727},{"stateMutability":"nonpayable","type":"function","name":"revert_transfer_ownership","inputs":[],"outputs":[],"gas":23102},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[],"gas":90405},{"stateMutability":"nonpayable","type":"function","name":"donate_admin_fees","inputs":[],"outputs":[],"gas":63231},{"stateMutability":"nonpayable","type":"function","name":"kill_me","inputs":[],"outputs":[],"gas":40385},{"stateMutability":"nonpayable","type":"function","name":"unkill_me","inputs":[],"outputs":[],"gas":23222},{"stateMutability":"nonpayable","type":"function","name":"set_aave_referral","inputs":[{"name":"referral_code","type":"uint256"}],"outputs":[],"gas":38352},{"stateMutability":"nonpayable","type":"function","name":"set_reward_receiver","inputs":[{"name":"_reward_receiver","type":"address"}],"outputs":[],"gas":38385},{"stateMutability":"nonpayable","type":"function","name":"set_admin_fee_receiver","inputs":[{"name":"_admin_fee_receiver","type":"address"}],"outputs":[],"gas":38415},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":3333},{"stateMutability":"view","type":"function","name":"underlying_coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":3363},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3393},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3378},{"stateMutability":"view","type":"function","name":"offpeg_fee_multiplier","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3408},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3438},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3468},{"stateMutability":"view","type":"function","name":"lp_token","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3498},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3528},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3558},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3588},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3618},{"stateMutability":"view","type":"function","name":"admin_actions_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3648},{"stateMutability":"view","type":"function","name":"transfer_ownership_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3678},{"stateMutability":"view","type":"function","name":"future_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3708},{"stateMutability":"view","type":"function","name":"future_admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3738},{"stateMutability":"view","type":"function","name":"future_offpeg_fee_multiplier","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3768},{"stateMutability":"view","type":"function","name":"future_owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3798},{"stateMutability":"view","type":"function","name":"reward_receiver","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3828},{"stateMutability":"view","type":"function","name":"admin_fee_receiver","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3858}] \ No newline at end of file