编译器
0.5.16+commit.9c3226ce
文件 1 的 19:AeroVaultToken.sol
pragma solidity =0.5.16;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/ownership/Ownable.sol";
import "./PoolToken.sol";
import "./interfaces/IOptiSwap.sol";
import "./interfaces/IVeloVoter.sol";
import "./interfaces/IVeloV2PoolFactory.sol";
import "./interfaces/IVeloV2Gauge.sol";
import "./interfaces/IVeloV2Pool.sol";
import "./interfaces/IVeloV2Router.sol";
import "./interfaces/IBaseV1Pair.sol";
import "./interfaces/IAeroVaultToken.sol";
import "./interfaces/IUniswapV2Pair.sol";
import "./interfaces/IERC20.sol";
import "./libraries/SafeToken.sol";
import "./libraries/Math.sol";
interface OptiSwapPair {
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
contract AeroVaultToken is IAeroVaultToken, PoolToken {
using SafeToken for address;
bool public constant isVaultToken = true;
bool public constant stable = false;
address public optiSwap;
address public router;
address public voter;
address public gauge;
address public pairFactory;
address public rewardsToken;
address public WETH;
address public reinvestFeeTo;
address public token0;
address public token1;
uint256 public constant MIN_REINVEST_BOUNTY = 0;
uint256 public constant MAX_REINVEST_BOUNTY = 0.05e18;
uint256 public REINVEST_BOUNTY = 0.02e18;
uint256 public constant MIN_REINVEST_FEE = 0;
uint256 public constant MAX_REINVEST_FEE = 0.05e18;
uint256 public REINVEST_FEE = 0.02e18;
uint256 public constant MIN_WITHDRAW_FEE_BPS = 0;
uint256 public constant MAX_WITHDRAW_FEE_BPS = 100;
uint256 public WITHDRAW_FEE = 1;
uint256 public constant MAX_BPS = 10000;
address[] reinvestorList;
mapping(address => bool) reinvestorEnabled;
event Reinvest(address indexed caller, uint256 reward, uint256 bounty, uint256 fee);
event UpdateReinvestBounty(uint256 _newReinvestBounty);
event UpdateReinvestFee(uint256 _newReinvestFee);
event UpdateWithdrawFee(uint256 _newWithdrawFee);
event UpdateReinvestFeeTo(address _newReinvestFeeTo);
function _initialize(
address _underlying,
address _optiSwap,
address _router,
address _voter,
address _pairFactory,
address _rewardsToken,
address _reinvestFeeTo
) external {
require(factory == address(0), "VaultToken: FACTORY_ALREADY_SET");
factory = msg.sender;
_setName("Tarot Vault Token", "vTAROT");
underlying = _underlying;
optiSwap = _optiSwap;
voter = _voter;
gauge = IVeloVoter(voter).gauges(underlying);
require(gauge != address(0), "VaultToken: NO_GAUGE");
router = _router;
pairFactory = _pairFactory;
WETH = IVeloV2Router(_router).weth();
(token0, token1) = IBaseV1Pair(_underlying).tokens();
rewardsToken = _rewardsToken;
reinvestFeeTo = _reinvestFeeTo;
rewardsToken.safeApprove(address(router), uint256(-1));
WETH.safeApprove(address(router), uint256(-1));
underlying.safeApprove(address(gauge), uint256(-1));
}
function reinvestorListLength() external view returns (uint256) {
return reinvestorList.length;
}
function reinvestorListItem(uint256 index) external view returns (address) {
return reinvestorList[index];
}
function isReinvestorEnabled(address reinvestor) external view returns (bool) {
return reinvestorEnabled[reinvestor];
}
function _addReinvestor(address reinvestor) private {
require(!reinvestorEnabled[reinvestor], "VaultToken: REINVESTOR_ENABLED");
reinvestorEnabled[reinvestor] = true;
reinvestorList.push(reinvestor);
}
function addReinvestor(address reinvestor) external onlyFactoryOwner {
_addReinvestor(reinvestor);
}
function _indexOfReinvestor(address reinvestor) private view returns (uint256 index) {
uint256 count = reinvestorList.length;
for (uint256 i = 0; i < count; i++) {
if (reinvestorList[i] == reinvestor) {
return i;
}
}
require(false, "VaultToken: REINVESTOR_NOT_FOUND");
}
function removeReinvestor(address reinvestor) external onlyFactoryOwner {
require(reinvestorEnabled[reinvestor], "VaultToken: REINVESTOR_ENABLED");
uint256 index = _indexOfReinvestor(reinvestor);
address last = reinvestorList[reinvestorList.length - 1];
reinvestorList[index] = last;
reinvestorList.pop();
delete reinvestorEnabled[reinvestor];
}
function updateReinvestBounty(uint256 _newReinvestBounty) external onlyFactoryOwner {
require(_newReinvestBounty >= MIN_REINVEST_BOUNTY && _newReinvestBounty <= MAX_REINVEST_BOUNTY, "VaultToken: INVLD_REINVEST_BOUNTY");
REINVEST_BOUNTY = _newReinvestBounty;
emit UpdateReinvestBounty(_newReinvestBounty);
}
function updateReinvestFee(uint256 _newReinvestFee) external onlyFactoryOwner {
require(_newReinvestFee >= MIN_REINVEST_FEE && _newReinvestFee <= MAX_REINVEST_FEE, "VaultToken: INVLD_REINVEST_FEE");
REINVEST_FEE = _newReinvestFee;
emit UpdateReinvestFee(_newReinvestFee);
}
function updateWithdrawFee(uint256 _newWithdrawFee) external onlyFactoryOwner {
require(_newWithdrawFee >= MIN_WITHDRAW_FEE_BPS && _newWithdrawFee <= MAX_WITHDRAW_FEE_BPS, "VaultToken: INVLD_WITHDRAW_FEE");
WITHDRAW_FEE = _newWithdrawFee;
emit UpdateWithdrawFee(_newWithdrawFee);
}
function updateReinvestFeeTo(address _newReinvestFeeTo) external onlyFactoryOwner {
reinvestFeeTo = _newReinvestFeeTo;
emit UpdateReinvestFeeTo(_newReinvestFeeTo);
}
function _update() internal {
uint256 _totalBalance = IVeloV2Gauge(gauge).balanceOf(address(this));
totalBalance = _totalBalance;
emit Sync(_totalBalance);
}
function mint(address minter) external nonReentrant update returns (uint256 mintTokens) {
uint256 mintAmount = underlying.myBalance();
uint256 _totalBalanceBefore = IVeloV2Gauge(gauge).balanceOf(address(this));
IVeloV2Gauge(gauge).deposit(mintAmount);
uint256 _totalBalanceAfter = IVeloV2Gauge(gauge).balanceOf(address(this));
mintTokens = _totalBalanceAfter.sub(_totalBalanceBefore).mul(1e18).div(exchangeRate());
if (totalSupply == 0) {
mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY);
}
require(mintTokens > 0, "VaultToken: MINT_AMOUNT_ZERO");
_mint(minter, mintTokens);
emit Mint(msg.sender, minter, mintAmount, mintTokens);
}
function redeem(address redeemer) external nonReentrant update returns (uint256 redeemAmount) {
uint256 redeemTokens = balanceOf[address(this)];
redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18);
{
uint256 redeemFee = redeemAmount.mul(WITHDRAW_FEE).div(MAX_BPS);
redeemAmount = redeemAmount.sub(redeemFee);
}
require(redeemAmount > 0, "VaultToken: REDEEM_AMOUNT_ZERO");
require(redeemAmount <= totalBalance, "VaultToken: INSUFFICIENT_CASH");
_burn(address(this), redeemTokens);
IVeloV2Gauge(gauge).withdraw(redeemAmount);
_safeTransfer(redeemer, redeemAmount);
emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens);
}
function _optimalDepositA(
uint256 _amountA,
uint256 _reserveA
) internal view returns (uint256) {
uint256 swapFee = IVeloV2PoolFactory(pairFactory).getFee(underlying, false);
uint256 swapFeeFactor = uint256(10000).sub(swapFee);
uint256 a = uint256(10000).add(swapFeeFactor).mul(_reserveA);
uint256 b = _amountA.mul(10000).mul(_reserveA).mul(4).mul(swapFeeFactor);
uint256 c = Math.sqrt(a.mul(a).add(b));
uint256 d = uint256(2).mul(swapFeeFactor);
return c.sub(a).div(d);
}
function approveRouter(address token, uint256 amount) internal {
if (IERC20(token).allowance(address(this), router) >= amount) return;
token.safeApprove(address(router), uint256(-1));
}
function swapExactTokensForTokens(
address tokenIn,
address tokenOut,
uint256 amount
) internal {
approveRouter(tokenIn, amount);
IVeloV2Router.Route[] memory routes = new IVeloV2Router.Route[](1);
routes[0].from = tokenIn;
routes[0].to = tokenOut;
routes[0].stable = false;
routes[0].factory = IVeloV2Pool(underlying).factory();
IVeloV2Router(router).swapExactTokensForTokens(amount, 0, routes, address(this), block.timestamp);
}
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountA,
uint256 amountB
) internal returns (uint256 liquidity) {
approveRouter(tokenA, amountA);
approveRouter(tokenB, amountB);
(, , liquidity) = IVeloV2Router(router).addLiquidity(tokenA, tokenB, false, amountA, amountB, 0, 0, address(this), block.timestamp);
}
function swapTokensForBestAmountOut(
IOptiSwap _optiSwap,
address tokenIn,
address tokenOut,
uint256 amountIn
) internal returns (uint256 amountOut) {
if (tokenIn == tokenOut) {
return amountIn;
}
address pair;
(pair, amountOut) = _optiSwap.getBestAmountOut(amountIn, tokenIn, tokenOut);
require(pair != address(0), "NO_PAIR");
tokenIn.safeTransfer(pair, amountIn);
if (tokenIn < tokenOut) {
OptiSwapPair(pair).swap(0, amountOut, address(this), new bytes(0));
} else {
OptiSwapPair(pair).swap(amountOut, 0, address(this), new bytes(0));
}
}
function optiSwapExactTokensForTokens(
address tokenIn,
address tokenOut,
uint256 amountIn
) internal returns (uint256 amountOut) {
if (tokenIn == tokenOut) {
return amountIn;
}
IOptiSwap _optiSwap = IOptiSwap(optiSwap);
address nextHop = _optiSwap.getBridgeToken(tokenIn);
if (nextHop == tokenOut) {
return swapTokensForBestAmountOut(_optiSwap, tokenIn, tokenOut, amountIn);
}
address waypoint = _optiSwap.getBridgeToken(tokenOut);
if (tokenIn == waypoint) {
return swapTokensForBestAmountOut(_optiSwap, tokenIn, tokenOut, amountIn);
}
uint256 hopAmountOut;
if (nextHop != tokenIn) {
hopAmountOut = swapTokensForBestAmountOut(_optiSwap, tokenIn, nextHop, amountIn);
} else {
hopAmountOut = amountIn;
}
if (nextHop == waypoint) {
return swapTokensForBestAmountOut(_optiSwap, nextHop, tokenOut, hopAmountOut);
} else if (waypoint == tokenOut) {
return optiSwapExactTokensForTokens(nextHop, tokenOut, hopAmountOut);
} else {
uint256 waypointAmountOut = optiSwapExactTokensForTokens(nextHop, waypoint, hopAmountOut);
return swapTokensForBestAmountOut(_optiSwap, waypoint, tokenOut, waypointAmountOut);
}
}
function _getReward() internal returns (uint256 amount) {
IVeloV2Gauge(gauge).getReward(address(this));
return rewardsToken.myBalance();
}
function getReward() external nonReentrant returns (uint256) {
require(msg.sender == tx.origin || reinvestorEnabled[msg.sender]);
return _getReward();
}
function reinvest() external nonReentrant update {
require(msg.sender == tx.origin || reinvestorEnabled[msg.sender]);
uint256 reward = _getReward();
if (reward == 0) return;
uint256 bounty = reward.mul(REINVEST_BOUNTY) / 1e18;
if (bounty > 0) {
rewardsToken.safeTransfer(msg.sender, bounty);
}
uint256 fee = reward.mul(REINVEST_FEE) / 1e18;
if (fee > 0) {
rewardsToken.safeTransfer(reinvestFeeTo, fee);
}
address tokenA;
address tokenB;
if (token0 == rewardsToken || token1 == rewardsToken) {
(tokenA, tokenB) = token0 == rewardsToken ? (token0, token1) : (token1, token0);
} else {
if (token1 == WETH) {
(tokenA, tokenB) = (token1, token0);
} else {
(tokenA, tokenB) = (token0, token1);
}
optiSwapExactTokensForTokens(rewardsToken, tokenA, reward.sub(bounty.add(fee)));
}
uint256 totalAmountA = tokenA.myBalance();
assert(totalAmountA > 0);
(uint256 r0, uint256 r1, ) = IUniswapV2Pair(underlying).getReserves();
uint256 reserveA = tokenA == token0 ? r0 : r1;
uint256 swapAmount = _optimalDepositA(totalAmountA, reserveA);
swapExactTokensForTokens(tokenA, tokenB, swapAmount);
uint256 liquidity = addLiquidity(tokenA, tokenB, totalAmountA.sub(swapAmount), tokenB.myBalance());
IVeloV2Gauge(gauge).deposit(liquidity);
emit Reinvest(msg.sender, reward, bounty, fee);
}
function adminClaimRewards() external onlyFactoryOwner nonReentrant {
IVeloV2Gauge(gauge).getReward(address(this));
}
function adminRescueTokens(address _to, address[] calldata _tokens) external onlyFactoryOwner nonReentrant {
require(_to != address(0), "VaultToken: INVLD_TO");
for (uint256 i = 0; i < _tokens.length; i++) {
address token = _tokens[i];
require(token != underlying, "VaultToken: IS_UNDERLYING");
require(token != rewardsToken, "VaultToken: IS_REWARDS_TOKEN");
require(token != token0, "VaultToken: IS_TOKEN_0");
require(token != token1, "VaultToken: IS_TOKEN_1");
uint256 tokenBalance = token.myBalance();
if (tokenBalance > 0) {
token.safeTransfer(_to, tokenBalance);
}
}
}
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
)
{
(uint _reserve0, uint _reserve1, uint _blockTimestampLast) = IUniswapV2Pair(underlying).getReserves();
reserve0 = safe112(_reserve0);
reserve1 = safe112(_reserve1);
blockTimestampLast = uint32(_blockTimestampLast % 2**32);
if (totalSupply == 0) return (reserve0, reserve1, blockTimestampLast);
uint256 _totalBalance = totalBalance;
uint256 _totalSupply = IUniswapV2Pair(underlying).totalSupply();
reserve0 = safe112(_totalBalance.mul(reserve0).div(_totalSupply));
reserve1 = safe112(_totalBalance.mul(reserve1).div(_totalSupply));
require(reserve0 > 100 && reserve1 > 100, "VaultToken: INSUFFICIENT_RESERVES");
}
function observationLength() external view returns (uint) {
return IBaseV1Pair(underlying).observationLength();
}
function observations(uint index)
external
view
returns (
uint timestamp,
uint reserve0Cumulative,
uint reserve1Cumulative
)
{
return IBaseV1Pair(underlying).observations(index);
}
function currentCumulativePrices()
external
view
returns (
uint reserve0Cumulative,
uint reserve1Cumulative,
uint timestamp
)
{
return IBaseV1Pair(underlying).currentCumulativePrices();
}
function safe112(uint256 n) internal pure returns (uint112) {
require(n < 2**112, "VaultToken: SAFE112");
return uint112(n);
}
function getBlockTimestamp() public view returns (uint32) {
return uint32(block.timestamp % 2**32);
}
modifier onlyFactoryOwner() {
require(Ownable(factory).owner() == msg.sender, "NOT_AUTHORIZED");
_;
}
}
文件 2 的 19:Context.sol
pragma solidity ^0.5.0;
contract Context {
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
文件 3 的 19:IAeroVaultToken.sol
pragma solidity >=0.5.0;
interface IAeroVaultToken {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(address indexed sender, address indexed minter, uint256 mintAmount, uint256 mintTokens);
event Redeem(address indexed sender, address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens);
event Sync(uint256 totalBalance);
function underlying() external view returns (address);
function factory() external view returns (address);
function totalBalance() external view returns (uint256);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function exchangeRate() external view returns (uint256);
function mint(address minter) external returns (uint256 mintTokens);
function redeem(address redeemer) external returns (uint256 redeemAmount);
function skim(address to) external;
function sync() external;
function _setFactory() external;
event Reinvest(address indexed caller, uint256 reward, uint256 bounty, uint256 fee);
function isVaultToken() external pure returns (bool);
function stable() external pure returns (bool);
function optiSwap() external view returns (address);
function router() external view returns (address);
function voter() external view returns (address);
function pairFactory() external view returns (address);
function rewardsToken() external view returns (address);
function WETH() external view returns (address);
function reinvestFeeTo() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function REINVEST_BOUNTY() external view returns (uint256);
function REINVEST_FEE() external view returns (uint256);
function WITHDRAW_FEE() external view returns (uint256);
function reinvestorListLength() external view returns (uint256);
function reinvestorListItem(uint256 index) external view returns (address);
function isReinvestorEnabled(address reinvestor) external view returns (bool);
function addReinvestor(address reinvestor) external;
function removeReinvestor(address reinvestor) external;
function updateReinvestBounty(uint256 _newReinvestBounty) external;
function updateReinvestFee(uint256 _newReinvestFee) external;
function updateWithdrawFee(uint256 _newWithdrawFee) external;
function updateReinvestFeeTo(address _newReinvestFeeTo) external;
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function observationLength() external view returns (uint);
function observations(uint index)
external
view
returns (
uint timestamp,
uint reserve0Cumulative,
uint reserve1Cumulative
);
function currentCumulativePrices()
external
view
returns (
uint reserve0Cumulative,
uint reserve1Cumulative,
uint timestamp
);
function _initialize(
address _underlying,
address _optiSwap,
address _router,
address _voter,
address _pairFactory,
address _rewardsToken,
address _reinvestFeeTo
) external;
function reinvest() external;
function getReward() external returns (uint256);
function getBlockTimestamp() external view returns (uint32);
function adminClaimRewards() external;
function adminRescueTokens(address _to, address[] calldata _tokens) external;
}
文件 4 的 19:IBaseV1Pair.sol
pragma solidity >=0.5.0;
interface IBaseV1Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function stable() external view returns (bool);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function token0() external view returns (address);
function token1() external view returns (address);
function tokens() external view returns (address, address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function observationLength() external view returns (uint);
function observations(uint) external view returns (
uint timestamp,
uint reserve0Cumulative,
uint reserve1Cumulative
);
function currentCumulativePrices() external view returns (
uint reserve0Cumulative,
uint reserve1Cumulative,
uint timestamp
);
function metadata() external view returns (uint, uint, uint, uint, bool, address, address);
}
文件 5 的 19:IERC20.sol
pragma solidity >=0.5.0;
interface IERC20 {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
}
文件 6 的 19:IOptiSwap.sol
pragma solidity >=0.5.0;
interface IOptiSwap {
function weth() external view returns (address);
function bridgeFromTokens(uint256 index) external view returns (address token);
function bridgeFromTokensLength() external view returns (uint256);
function getBridgeToken(address _token) external view returns (address bridgeToken);
function addBridgeToken(address _token, address _bridgeToken) external;
function getDexInfo(uint256 index) external view returns (address dex, address handler);
function dexListLength() external view returns (uint256);
function indexOfDex(address _dex) external view returns (uint256);
function getDexEnabled(address _dex) external view returns (bool);
function addDex(address _dex, address _handler) external;
function removeDex(address _dex) external;
function getBestAmountOut(
uint256 _amountIn,
address _tokenIn,
address _tokenOut
) external view returns (address pair, uint256 amountOut);
}
文件 7 的 19:IPoolToken.sol
pragma solidity >=0.5.0;
interface IPoolToken {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
);
event Redeem(
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
);
event Sync(uint256 totalBalance);
function underlying() external view returns (address);
function factory() external view returns (address);
function totalBalance() external view returns (uint256);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function exchangeRate() external view returns (uint256);
function mint(address minter) external returns (uint256 mintTokens);
function redeem(address redeemer) external returns (uint256 redeemAmount);
function skim(address to) external;
function sync() external;
function _setFactory() external;
}
文件 8 的 19:IUniswapV2Pair.sol
pragma solidity >=0.5.0;
interface IUniswapV2Pair {
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Transfer(address indexed from, address indexed to, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
}
文件 9 的 19:IVeloV2Gauge.sol
pragma solidity >=0.5.0;
interface IVeloV2Gauge {
function notifyRewardAmount(uint amount) external;
function getReward(address account) external;
function left() external view returns (uint);
function isPool() external view returns (bool);
function earned(address account) external view returns (uint);
function balanceOf(address account) external view returns (uint);
function deposit(uint256 amount) external;
function withdraw(uint256 amount) external;
}
文件 10 的 19:IVeloV2Pool.sol
pragma solidity >=0.5.0;
interface IVeloV2Pool {
function factory() external view returns (address);
}
文件 11 的 19:IVeloV2PoolFactory.sol
pragma solidity >=0.5.0;
interface IVeloV2PoolFactory {
function allPoolsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function getPair(address tokenA, address tokenB, bool stable) external view returns (address);
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair);
function getFee(address pool, bool _stable) external view returns (uint);
}
文件 12 的 19:IVeloV2Router.sol
pragma solidity >=0.5.0;
pragma experimental ABIEncoderV2;
interface IVeloV2Router {
struct Route {
address from;
address to;
bool stable;
address factory;
}
function weth() external view returns (address);
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
Route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
}
文件 13 的 19:IVeloVoter.sol
pragma solidity >=0.5.0;
interface IVeloVoter {
function _ve() external view returns (address);
function governor() external view returns (address);
function emergencyCouncil() external view returns (address);
function attachTokenToGauge(uint _tokenId, address account) external;
function detachTokenFromGauge(uint _tokenId, address account) external;
function emitDeposit(uint _tokenId, address account, uint amount) external;
function emitWithdraw(uint _tokenId, address account, uint amount) external;
function isWhitelisted(address token) external view returns (bool);
function notifyRewardAmount(uint amount) external;
function distribute(address _gauge) external;
function gauges(address token) external view returns (address);
}
文件 14 的 19:Math.sol
pragma solidity =0.5.16;
library Math {
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x < y ? x : y;
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}
文件 15 的 19:Ownable.sol
pragma solidity ^0.5.0;
import "../GSN/Context.sol";
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 16 的 19:PoolToken.sol
pragma solidity =0.5.16;
import "./TarotERC20.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IPoolToken.sol";
import "./libraries/SafeMath.sol";
contract PoolToken is IPoolToken, TarotERC20 {
uint256 internal constant initialExchangeRate = 1e18;
address public underlying;
address public factory;
uint256 public totalBalance;
uint256 public constant MINIMUM_LIQUIDITY = 1000;
event Mint(
address indexed sender,
address indexed minter,
uint256 mintAmount,
uint256 mintTokens
);
event Redeem(
address indexed sender,
address indexed redeemer,
uint256 redeemAmount,
uint256 redeemTokens
);
event Sync(uint256 totalBalance);
function _setFactory() external {
require(factory == address(0), "Tarot: FACTORY_ALREADY_SET");
factory = msg.sender;
}
function _update() internal {
totalBalance = IERC20(underlying).balanceOf(address(this));
emit Sync(totalBalance);
}
function exchangeRate() public view returns (uint256) {
uint256 _totalSupply = totalSupply;
uint256 _totalBalance = totalBalance;
if (_totalSupply == 0 || _totalBalance == 0) return initialExchangeRate;
return _totalBalance.mul(1e18).div(_totalSupply);
}
function mint(address minter)
external
nonReentrant
update
returns (uint256 mintTokens)
{
uint256 balance = IERC20(underlying).balanceOf(address(this));
uint256 mintAmount = balance.sub(totalBalance);
mintTokens = mintAmount.mul(1e18).div(exchangeRate());
if (totalSupply == 0) {
mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY);
}
require(mintTokens > 0, "Tarot: MINT_AMOUNT_ZERO");
_mint(minter, mintTokens);
emit Mint(msg.sender, minter, mintAmount, mintTokens);
}
function redeem(address redeemer)
external
nonReentrant
update
returns (uint256 redeemAmount)
{
uint256 redeemTokens = balanceOf[address(this)];
redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18);
require(redeemAmount > 0, "Tarot: REDEEM_AMOUNT_ZERO");
require(redeemAmount <= totalBalance, "Tarot: INSUFFICIENT_CASH");
_burn(address(this), redeemTokens);
_safeTransfer(redeemer, redeemAmount);
emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens);
}
function skim(address to) external nonReentrant {
_safeTransfer(
to,
IERC20(underlying).balanceOf(address(this)).sub(totalBalance)
);
}
function sync() external nonReentrant update {}
bytes4 private constant SELECTOR =
bytes4(keccak256(bytes("transfer(address,uint256)")));
function _safeTransfer(address to, uint256 amount) internal {
(bool success, bytes memory data) = underlying.call(
abi.encodeWithSelector(SELECTOR, to, amount)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"Tarot: TRANSFER_FAILED"
);
}
bool internal _notEntered = true;
modifier nonReentrant() {
require(_notEntered, "Tarot: REENTERED");
_notEntered = false;
_;
_notEntered = true;
}
modifier update() {
_;
_update();
}
}
文件 17 的 19:SafeMath.sol
pragma solidity =0.5.16;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function add(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, errorMessage);
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction underflow");
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function mul(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, errorMessage);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
文件 18 的 19:SafeToken.sol
pragma solidity 0.5.16;
interface ERC20Interface {
function balanceOf(address user) external view returns (uint256);
}
library SafeToken {
function myBalance(address token) internal view returns (uint256) {
return ERC20Interface(token).balanceOf(address(this));
}
function balanceOf(address token, address user)
internal
view
returns (uint256)
{
return ERC20Interface(token).balanceOf(user);
}
function safeApprove(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x095ea7b3, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"!safeApprove"
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0xa9059cbb, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"!safeTransfer"
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"!safeTransferFrom"
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call.value(value)(new bytes(0));
require(success, "!safeTransferETH");
}
}
文件 19 的 19:TarotERC20.sol
pragma solidity =0.5.16;
import "./libraries/SafeMath.sol";
contract TarotERC20 {
using SafeMath for uint256;
string public name;
string public symbol;
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
bytes32 public DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
constructor() public {}
function _setName(string memory _name, string memory _symbol) internal {
name = _name;
symbol = _symbol;
uint256 chainId;
assembly {
chainId := chainid
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes(_name)),
keccak256(bytes("1")),
chainId,
address(this)
)
);
}
function _mint(address to, uint256 value) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _approve(
address owner,
address spender,
uint256 value
) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer(
address from,
address to,
uint256 value
) internal {
balanceOf[from] = balanceOf[from].sub(
value,
"Tarot: TRANSFER_TOO_HIGH"
);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from, to, value);
}
function approve(address spender, uint256 value) external returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transfer(address to, uint256 value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool) {
if (allowance[from][msg.sender] != uint256(-1)) {
allowance[from][msg.sender] = allowance[from][msg.sender].sub(
value,
"Tarot: TRANSFER_NOT_ALLOWED"
);
}
_transfer(from, to, value);
return true;
}
function _checkSignature(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s,
bytes32 typehash
) internal {
require(deadline >= block.timestamp, "Tarot: EXPIRED");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(
abi.encode(
typehash,
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(
recoveredAddress != address(0) && recoveredAddress == owner,
"Tarot: INVALID_SIGNATURE"
);
}
bytes32 public constant PERMIT_TYPEHASH =
0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
_checkSignature(
owner,
spender,
value,
deadline,
v,
r,
s,
PERMIT_TYPEHASH
);
_approve(owner, spender, value);
}
}
{
"compilationTarget": {
"contracts/AeroVaultToken.sol": "AeroVaultToken"
},
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bounty","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Reinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalBalance","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newReinvestBounty","type":"uint256"}],"name":"UpdateReinvestBounty","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newReinvestFee","type":"uint256"}],"name":"UpdateReinvestFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newReinvestFeeTo","type":"address"}],"name":"UpdateReinvestFeeTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newWithdrawFee","type":"uint256"}],"name":"UpdateWithdrawFee","type":"event"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_REINVEST_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_REINVEST_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_WITHDRAW_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_REINVEST_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_REINVEST_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_WITHDRAW_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"REINVEST_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"REINVEST_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WITHDRAW_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"address","name":"_optiSwap","type":"address"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_reinvestFeeTo","type":"address"}],"name":"_initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"_setFactory","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"reinvestor","type":"address"}],"name":"addReinvestor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"adminClaimRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"adminRescueTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentCumulativePrices","outputs":[{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBlockTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"reserve0","type":"uint112"},{"internalType":"uint112","name":"reserve1","type":"uint112"},{"internalType":"uint32","name":"blockTimestampLast","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"getReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"reinvestor","type":"address"}],"name":"isReinvestorEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isVaultToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"mintTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"observationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"optiSwap","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pairFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"redeemer","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"redeemAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"reinvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"reinvestFeeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"reinvestorListItem","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reinvestorListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"reinvestor","type":"address"}],"name":"removeReinvestor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sync","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newReinvestBounty","type":"uint256"}],"name":"updateReinvestBounty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newReinvestFee","type":"uint256"}],"name":"updateReinvestFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newReinvestFeeTo","type":"address"}],"name":"updateReinvestFeeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_newWithdrawFee","type":"uint256"}],"name":"updateWithdrawFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]