编译器
0.8.13+commit.abaa5c0e
文件 1 的 18:Address.sol
pragma solidity 0.8.13;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 18:BaseStrategy.sol
pragma solidity 0.8.13;
import "../YakStrategyV3.sol";
import "../interfaces/IWGAS.sol";
import "../lib/SafeERC20.sol";
import "./../interfaces/ISimpleRouter.sol";
abstract contract BaseStrategy is YakStrategyV3 {
using SafeERC20 for IERC20;
IWGAS internal immutable WGAS;
struct BaseStrategySettings {
address gasToken;
address[] rewards;
address simpleRouter;
}
struct Reward {
address reward;
uint256 amount;
}
address[] public supportedRewards;
ISimpleRouter public simpleRouter;
event AddReward(address rewardToken);
event RemoveReward(address rewardToken);
event UpdateRouter(address oldRouter, address newRouter);
constructor(BaseStrategySettings memory _settings, StrategySettings memory _strategySettings)
YakStrategyV3(_strategySettings)
{
WGAS = IWGAS(_settings.gasToken);
supportedRewards = _settings.rewards;
simpleRouter = ISimpleRouter(_settings.simpleRouter);
require(_strategySettings.minTokensToReinvest > 0, "BaseStrategy::Invalid configuration");
emit Reinvest(0, 0);
}
function updateRouter(address _router) public onlyDev {
emit UpdateRouter(address(simpleRouter), _router);
simpleRouter = ISimpleRouter(_router);
}
function addReward(address _rewardToken) public onlyDev {
bool found;
for (uint256 i = 0; i < supportedRewards.length; i++) {
if (_rewardToken == supportedRewards[i]) {
found = true;
}
}
require(!found, "BaseStrategy::Reward already configured!");
supportedRewards.push(_rewardToken);
emit AddReward(_rewardToken);
}
function removeReward(address _rewardToken) public onlyDev {
bool found;
for (uint256 i = 0; i < supportedRewards.length; i++) {
if (_rewardToken == supportedRewards[i]) {
found = true;
supportedRewards[i] = supportedRewards[supportedRewards.length - 1];
}
}
require(found, "BaseStrategy::Reward not configured!");
supportedRewards.pop();
emit RemoveReward(_rewardToken);
}
function getSupportedRewardsLength() public view returns (uint256) {
return supportedRewards.length;
}
function calculateDepositFee(uint256 _amount) public view returns (uint256) {
return _calculateDepositFee(_amount);
}
function calculateWithdrawFee(uint256 _amount) public view returns (uint256) {
return _calculateWithdrawFee(_amount);
}
function deposit(uint256 _amount) external override {
_deposit(msg.sender, _amount);
}
function depositWithPermit(uint256 _amount, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s)
external
override
{
depositToken.permit(msg.sender, address(this), _amount, _deadline, _v, _r, _s);
_deposit(msg.sender, _amount);
}
function depositFor(address _account, uint256 _amount) external override {
_deposit(_account, _amount);
}
function _deposit(address _account, uint256 _amount) internal {
require(DEPOSITS_ENABLED == true, "BaseStrategy::Deposits disabled");
_reinvest(true);
require(
depositToken.transferFrom(msg.sender, address(this), _amount), "BaseStrategy::Deposit token transfer failed"
);
uint256 depositFee = _calculateDepositFee(_amount);
_mint(_account, getSharesForDepositTokens(_amount - depositFee));
_stakeDepositTokens(_amount, depositFee);
emit Deposit(_account, _amount);
}
function _getDepositFeeBips() internal view virtual returns (uint256) {
return 0;
}
function _calculateDepositFee(uint256 _amount) internal view virtual returns (uint256) {
uint256 depositFeeBips = _getDepositFeeBips();
return (_amount * depositFeeBips) / _bip();
}
function withdraw(uint256 _amount) external override {
uint256 depositTokenAmount = getDepositTokensForShares(_amount);
require(depositTokenAmount > 0, "BaseStrategy::Withdraw amount too low");
uint256 withdrawAmount = _withdrawFromStakingContract(depositTokenAmount);
uint256 withdrawFee = _calculateWithdrawFee(depositTokenAmount);
depositToken.safeTransfer(msg.sender, withdrawAmount - withdrawFee);
_burn(msg.sender, _amount);
emit Withdraw(msg.sender, depositTokenAmount);
}
function _getWithdrawFeeBips() internal view virtual returns (uint256) {
return 0;
}
function _calculateWithdrawFee(uint256 _amount) internal view virtual returns (uint256) {
uint256 withdrawFeeBips = _getWithdrawFeeBips();
return (_amount * withdrawFeeBips) / _bip();
}
function reinvest() external override onlyEOA {
_reinvest(false);
}
function _convertPoolRewardsToRewardToken() private returns (uint256) {
_getRewards();
uint256 rewardTokenAmount = rewardToken.balanceOf(address(this));
uint256 count = supportedRewards.length;
for (uint256 i = 0; i < count; i++) {
address reward = supportedRewards[i];
if (reward == address(WGAS)) {
uint256 balance = address(this).balance;
if (balance > 0) {
WGAS.deposit{value: balance}();
}
if (address(rewardToken) == address(WGAS)) {
rewardTokenAmount += balance;
continue;
}
}
uint256 amount = IERC20(reward).balanceOf(address(this));
if (amount > 0 && reward != address(rewardToken)) {
FormattedOffer memory offer = simpleRouter.query(amount, reward, address(rewardToken));
rewardTokenAmount += _swap(offer);
}
}
return rewardTokenAmount;
}
function _reinvest(bool userDeposit) private {
uint256 amount = _convertPoolRewardsToRewardToken();
if (amount > MIN_TOKENS_TO_REINVEST) {
uint256 devFee = (amount * DEV_FEE_BIPS) / BIPS_DIVISOR;
if (devFee > 0) {
rewardToken.safeTransfer(feeCollector, devFee);
}
uint256 reinvestFee = userDeposit ? 0 : (amount * REINVEST_REWARD_BIPS) / BIPS_DIVISOR;
if (reinvestFee > 0) {
rewardToken.safeTransfer(msg.sender, reinvestFee);
}
uint256 depositTokenAmount = _convertRewardTokenToDepositToken(amount - devFee - reinvestFee);
if (depositTokenAmount > 0) {
uint256 depositFee = _calculateDepositFee(depositTokenAmount);
_stakeDepositTokens(depositTokenAmount, depositFee);
emit Reinvest(totalDeposits(), totalSupply);
}
}
}
function _convertRewardTokenToDepositToken(uint256 _fromAmount) internal virtual returns (uint256 toAmount) {
if (address(rewardToken) == address(depositToken)) return _fromAmount;
FormattedOffer memory offer = simpleRouter.query(_fromAmount, address(rewardToken), address(depositToken));
return _swap(offer);
}
function _stakeDepositTokens(uint256 _amount, uint256 _depositFee) private {
require(_amount > 0, "BaseStrategy::Stake amount too low");
_depositToStakingContract(_amount, _depositFee);
}
function _swap(FormattedOffer memory _offer) internal returns (uint256 amountOut) {
if (_offer.amounts.length > 0 && _offer.amounts[_offer.amounts.length - 1] > 0) {
IERC20(_offer.path[0]).approve(address(simpleRouter), _offer.amounts[0]);
return simpleRouter.swap(_offer);
}
return 0;
}
function checkReward() public view override returns (uint256) {
Reward[] memory rewards = _pendingRewards();
uint256 estimatedTotalReward = rewardToken.balanceOf(address(this));
for (uint256 i = 0; i < rewards.length; i++) {
address reward = rewards[i].reward;
if (reward == address(WGAS)) {
rewards[i].amount += address(this).balance;
}
if (reward == address(rewardToken)) {
estimatedTotalReward += rewards[i].amount;
} else if (reward > address(0)) {
uint256 balance = IERC20(reward).balanceOf(address(this));
uint256 amount = balance + rewards[i].amount;
if (amount > 0) {
FormattedOffer memory offer = simpleRouter.query(amount, reward, address(rewardToken));
estimatedTotalReward += offer.amounts.length > 1 ? offer.amounts[offer.amounts.length - 1] : 0;
}
}
}
return estimatedTotalReward;
}
function rescueDeployedFunds(uint256 _minReturnAmountAccepted) external override onlyOwner {
uint256 balanceBefore = depositToken.balanceOf(address(this));
_emergencyWithdraw();
uint256 balanceAfter = depositToken.balanceOf(address(this));
require(
balanceAfter - balanceBefore >= _minReturnAmountAccepted,
"BaseStrategy::Emergency withdraw minimum return amount not reached"
);
emit Reinvest(totalDeposits(), totalSupply);
if (DEPOSITS_ENABLED == true) {
disableDeposits();
}
}
function _bip() internal view virtual returns (uint256) {
return 10000;
}
function _depositToStakingContract(uint256 _amount, uint256 _depositFee) internal virtual;
function _withdrawFromStakingContract(uint256 _amount) internal virtual returns (uint256 withdrawAmount);
function _emergencyWithdraw() internal virtual;
function _getRewards() internal virtual;
function _pendingRewards() internal view virtual returns (Reward[] memory);
}
文件 3 的 18:Context.sol
pragma solidity 0.8.13;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 4 的 18:IBooster.sol
pragma solidity 0.8.13;
interface IBooster {
struct PoolInfo {
address lptoken;
address token;
address gauge;
address crvRewards;
bool shutdown;
}
function poolInfo(uint256 _pid) external view returns (PoolInfo memory);
function customMintRatio(uint256 _pid) external view returns (uint256);
function mintRatio() external view returns (uint256);
function penaltyShare() external view returns (uint256);
function reservoirMinter() external view returns (address);
function cvx() external view returns (address);
}
文件 5 的 18:IERC20.sol
pragma solidity 0.8.13;
interface IERC20 {
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 account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 6 的 18:IPoolDepositor.sol
pragma solidity 0.8.13;
interface IPoolDepositor {
function deposit(address _lptoken, uint256 _amount, uint256 _minLiquidity, bool _stake) external;
function withdraw(address _lptoken, uint256 _amount, uint256 _minOut, address _recipient) external;
function getWithdrawAmountOut(address _lptoken, uint256 _amount)
external
view
returns (uint256 amount, uint256 fee);
function getDepositAmountOut(address _lptoken, uint256 _amount)
external
view
returns (uint256 liquidity, uint256 reward);
function booster() external view returns (address);
function lpTokenToPid(address wombatAsset) external view returns (uint256);
}
文件 7 的 18:ISimpleRouter.sol
pragma solidity 0.8.13;
import "./../router/interfaces/IYakRouter.sol";
interface ISimpleRouter {
error UnsupportedSwap(address _tokenIn, address _tokenOut);
error InvalidConfiguration();
struct SwapConfig {
bool useYakSwapRouter;
uint8 yakSwapMaxSteps;
Path path;
}
struct Path {
address[] adapters;
address[] tokens;
}
function query(uint256 _amountIn, address _tokenIn, address _tokenOut)
external
view
returns (FormattedOffer memory trade);
function swap(FormattedOffer memory _trade) external returns (uint256 amountOut);
}
文件 8 的 18:ITokenMinter.sol
pragma solidity 0.8.13;
interface ITokenMinter {
function getFactAmounMint(uint256 _amount) external view returns (uint256 amount);
}
文件 9 的 18:IWGAS.sol
pragma solidity 0.8.13;
import "./IERC20.sol";
interface IWGAS is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
文件 10 的 18:IWombatAsset.sol
pragma solidity 0.8.13;
interface IWombatAsset {
function pool() external view returns (address);
function liability() external view returns (uint120);
function totalSupply() external view returns (uint256);
}
文件 11 的 18:IWombatPool.sol
pragma solidity 0.8.13;
interface IWombatPool {
function deposit(address to, uint256 amount, address token, uint256 deadline) external returns (uint256);
function withdraw(address token, uint256 liquidity, uint256 minimumAmount, address to, uint256 deadline)
external
returns (uint256);
function quotePotentialWithdraw(address token, uint256 liquidity) external view returns (uint256, uint256);
}
文件 12 的 18:IWombexRewardPool.sol
pragma solidity 0.8.13;
interface IWombexRewardPool {
function claimableRewards(address _account)
external
view
returns (address[] memory tokens, uint256[] memory amounts);
function balanceOf(address account) external view returns (uint256);
function getReward() external returns (bool);
function asset() external view returns (address);
function withdrawAndUnwrap(uint256 amount, bool claim) external;
function withdrawAllAndUnwrap(bool claim) external;
}
文件 13 的 18:IYakRouter.sol
pragma solidity 0.8.13;
struct Query {
address adapter;
address tokenIn;
address tokenOut;
uint256 amountOut;
}
struct Offer {
bytes amounts;
bytes adapters;
bytes path;
uint256 gasEstimate;
}
struct FormattedOffer {
uint256[] amounts;
address[] adapters;
address[] path;
uint256 gasEstimate;
}
struct Trade {
uint256 amountIn;
uint256 amountOut;
address[] path;
address[] adapters;
}
interface IYakRouter {
event UpdatedTrustedTokens(address[] _newTrustedTokens);
event UpdatedAdapters(address[] _newAdapters);
event UpdatedMinFee(uint256 _oldMinFee, uint256 _newMinFee);
event UpdatedFeeClaimer(address _oldFeeClaimer, address _newFeeClaimer);
event YakSwap(address indexed _tokenIn, address indexed _tokenOut, uint256 _amountIn, uint256 _amountOut);
function setTrustedTokens(address[] memory _trustedTokens) external;
function setAdapters(address[] memory _adapters) external;
function setFeeClaimer(address _claimer) external;
function setMinFee(uint256 _fee) external;
function trustedTokensCount() external view returns (uint256);
function adaptersCount() external view returns (uint256);
function queryAdapter(uint256 _amountIn, address _tokenIn, address _tokenOut, uint8 _index)
external
returns (uint256);
function queryNoSplit(uint256 _amountIn, address _tokenIn, address _tokenOut, uint8[] calldata _options)
external
view
returns (Query memory);
function queryNoSplit(uint256 _amountIn, address _tokenIn, address _tokenOut)
external
view
returns (Query memory);
function findBestPathWithGas(
uint256 _amountIn,
address _tokenIn,
address _tokenOut,
uint256 _maxSteps,
uint256 _gasPrice
) external view returns (FormattedOffer memory);
function findBestPath(uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps)
external
view
returns (FormattedOffer memory);
function swapNoSplit(Trade calldata _trade, address _to, uint256 _fee) external;
function swapNoSplitFromAVAX(Trade calldata _trade, address _to, uint256 _fee) external payable;
function swapNoSplitToAVAX(Trade calldata _trade, address _to, uint256 _fee) external;
function swapNoSplitWithPermit(
Trade calldata _trade,
address _to,
uint256 _fee,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) external;
function swapNoSplitToAVAXWithPermit(
Trade calldata _trade,
address _to,
uint256 _fee,
uint256 _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) external;
}
文件 14 的 18:Ownable.sol
pragma solidity 0.8.13;
import "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 15 的 18:SafeERC20.sol
pragma solidity 0.8.13;
import "../interfaces/IERC20.sol";
import "./Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 16 的 18:WombexStrategy.sol
pragma solidity 0.8.13;
import "../../BaseStrategy.sol";
import "./interfaces/IPoolDepositor.sol";
import "./interfaces/IWombexRewardPool.sol";
import "./interfaces/IWombatAsset.sol";
import "./interfaces/IWombatPool.sol";
import "./interfaces/IBooster.sol";
import "./interfaces/ITokenMinter.sol";
contract WombexStrategy is BaseStrategy {
using SafeERC20 for IERC20;
address private constant WOM = 0x7B5EB3940021Ec0e8e463D5dBB4B7B09a89DDF96;
address private constant WMX = 0x5190F06EaceFA2C552dc6BD5e763b81C73293293;
struct WombexStrategySettings {
address poolDepositor;
address rewardPool;
}
IPoolDepositor public immutable poolDepositor;
IWombexRewardPool public immutable rewardPool;
IWombatAsset public immutable wombatAsset;
IWombatPool public immutable wombatPool;
IBooster public immutable booster;
uint256 public immutable pid;
constructor(
WombexStrategySettings memory _wombexStrategySettings,
BaseStrategySettings memory baseStrategySettings,
StrategySettings memory _strategySettings
) BaseStrategy(baseStrategySettings, _strategySettings) {
poolDepositor = IPoolDepositor(_wombexStrategySettings.poolDepositor);
rewardPool = IWombexRewardPool(_wombexStrategySettings.rewardPool);
wombatAsset = IWombatAsset(rewardPool.asset());
wombatPool = IWombatPool(wombatAsset.pool());
booster = IBooster(poolDepositor.booster());
pid = poolDepositor.lpTokenToPid(rewardPool.asset());
}
function _depositToStakingContract(uint256 _amount, uint256) internal override {
depositToken.approve(address(poolDepositor), _amount);
poolDepositor.deposit(address(wombatAsset), _amount, 0, true);
}
function _withdrawFromStakingContract(uint256 _amount) internal override returns (uint256 _withdrawAmount) {
uint256 lpBalance = rewardPool.balanceOf(address(this));
uint256 liquidity = (_amount * lpBalance) / totalDeposits();
liquidity = liquidity > lpBalance ? lpBalance : liquidity;
rewardPool.withdrawAndUnwrap(liquidity, false);
(uint256 expectedAmount,) = wombatPool.quotePotentialWithdraw(address(depositToken), liquidity);
IERC20(address(wombatAsset)).approve(address(wombatPool), liquidity);
_withdrawAmount =
wombatPool.withdraw(address(depositToken), liquidity, expectedAmount, address(this), type(uint256).max);
}
function _emergencyWithdraw() internal override {
depositToken.approve(address(poolDepositor), 0);
rewardPool.withdrawAllAndUnwrap(false);
uint256 assetBalance = IERC20(address(wombatAsset)).balanceOf(address(this));
IERC20(address(wombatAsset)).approve(address(wombatPool), assetBalance);
wombatPool.withdraw(address(depositToken), assetBalance, 0, address(this), type(uint256).max);
}
function _pendingRewards() internal view override returns (Reward[] memory) {
(address[] memory tokens, uint256[] memory amounts) = rewardPool.claimableRewards(address(this));
Reward[] memory pendingRewards = new Reward[](tokens.length + 1);
uint256 womAmount;
for (uint256 i = 0; i < tokens.length; i++) {
pendingRewards[i] = Reward({reward: tokens[i], amount: amounts[i]});
if (tokens[i] == WOM) {
womAmount = amounts[i];
}
}
if (womAmount > 0) {
uint256 poolMintRatio = booster.customMintRatio(pid);
if (poolMintRatio == 0) {
poolMintRatio = booster.mintRatio();
}
if (poolMintRatio > 0) {
uint256 wmxAmount = (womAmount * poolMintRatio) / BIPS_DIVISOR;
address reservoirMinter = booster.reservoirMinter();
ITokenMinter tokenMinter =
reservoirMinter == address(0) ? ITokenMinter(booster.cvx()) : ITokenMinter(reservoirMinter);
pendingRewards[tokens.length] = Reward({reward: WMX, amount: tokenMinter.getFactAmounMint(wmxAmount)});
}
}
return pendingRewards;
}
function _getRewards() internal override {
rewardPool.getReward();
}
function totalDeposits() public view override returns (uint256) {
uint256 liquidity = rewardPool.balanceOf(address(this));
uint256 deposits = (wombatAsset.liability() * liquidity) / wombatAsset.totalSupply();
return fromWad(deposits, depositToken.decimals());
}
function fromWad(uint256 x, uint8 d) internal pure returns (uint256) {
if (d < 18) {
return (x / (10 ** (18 - d)));
} else if (d > 18) {
return x * 10 ** (d - 18);
}
return x;
}
}
文件 17 的 18:YakERC20.sol
pragma solidity 0.8.13;
import "./interfaces/IERC20.sol";
abstract contract YakERC20 {
string public name = "Yield Yak";
string public symbol = "YRT";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping(address => mapping(address => uint256)) internal allowances;
mapping(address => uint256) internal balances;
bytes32 public constant DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
bytes32 public constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
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() {}
function allowance(address account, address spender) external view returns (uint256) {
return allowances[account][spender];
}
function approve(address spender, uint256 amount) external returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function balanceOf(address account) external view returns (uint256) {
return balances[account];
}
function transfer(address dst, uint256 amount) external returns (bool) {
_transferTokens(msg.sender, dst, amount);
return true;
}
function transferFrom(
address src,
address dst,
uint256 amount
) external returns (bool) {
address spender = msg.sender;
uint256 spenderAllowance = allowances[src][spender];
if (spender != src && spenderAllowance != type(uint256).max) {
uint256 newAllowance = spenderAllowance - amount;
allowances[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
_transferTokens(src, dst, amount);
return true;
}
function _approve(
address owner,
address spender,
uint256 amount
) internal {
require(owner != address(0), "_approve::owner zero address");
require(spender != address(0), "_approve::spender zero address");
allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _transferTokens(
address from,
address to,
uint256 value
) internal {
require(to != address(0), "_transferTokens: cannot transfer to the zero address");
balances[from] = balances[from] - value;
balances[to] = balances[to] + value;
emit Transfer(from, to, value);
}
function _mint(address to, uint256 value) internal {
require(value > 0, "_mint::zero shares");
totalSupply = totalSupply + value;
balances[to] = balances[to] + value;
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
balances[from] = balances[from] - value;
totalSupply = totalSupply - value;
emit Transfer(from, address(0), value);
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(deadline >= block.timestamp, "permit::expired");
bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));
_validateSignedData(owner, encodeData, v, r, s);
_approve(owner, spender, value);
}
function _validateSignedData(
address signer,
bytes32 encodeData,
uint8 v,
bytes32 r,
bytes32 s
) internal view {
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", getDomainSeparator(), encodeData));
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == signer, "Arch::validateSig: invalid signature");
}
function getDomainSeparator() public view returns (bytes32) {
return
keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), VERSION_HASH, _getChainId(), address(this)));
}
function _getChainId() internal view returns (uint256) {
uint256 chainId;
assembly {
chainId := chainid()
}
return chainId;
}
}
文件 18 的 18:YakStrategyV3.sol
pragma solidity 0.8.13;
import "./YakERC20.sol";
import "./lib/Ownable.sol";
import "./lib/SafeERC20.sol";
import "./interfaces/IERC20.sol";
abstract contract YakStrategyV3 is YakERC20, Ownable {
using SafeERC20 for IERC20;
struct StrategySettings {
string name;
address owner;
address dev;
address feeCollector;
address depositToken;
address rewardToken;
uint256 minTokensToReinvest;
uint256 devFeeBips;
uint256 reinvestRewardBips;
}
IERC20 public immutable depositToken;
IERC20 public immutable rewardToken;
address public devAddr;
address public feeCollector;
uint256 public MIN_TOKENS_TO_REINVEST;
bool public DEPOSITS_ENABLED;
uint256 public REINVEST_REWARD_BIPS;
uint256 public DEV_FEE_BIPS;
uint256 internal constant BIPS_DIVISOR = 10000;
event Deposit(address indexed account, uint256 amount);
event Withdraw(address indexed account, uint256 amount);
event Reinvest(uint256 newTotalDeposits, uint256 newTotalSupply);
event Recovered(address token, uint256 amount);
event UpdateDevFee(uint256 oldValue, uint256 newValue);
event UpdateReinvestReward(uint256 oldValue, uint256 newValue);
event UpdateMinTokensToReinvest(uint256 oldValue, uint256 newValue);
event UpdateMaxTokensToDepositWithoutReinvest(uint256 oldValue, uint256 newValue);
event UpdateDevAddr(address oldValue, address newValue);
event UpdateFeeCollector(address oldValue, address newValue);
event DepositsEnabled(bool newValue);
modifier onlyEOA() {
require(tx.origin == msg.sender, "YakStrategy::onlyEOA");
_;
}
modifier onlyDev() {
require(msg.sender == devAddr, "YakStrategy::onlyDev");
_;
}
constructor(StrategySettings memory _strategySettings) {
name = _strategySettings.name;
depositToken = IERC20(_strategySettings.depositToken);
rewardToken = IERC20(_strategySettings.rewardToken);
devAddr = msg.sender;
updateMinTokensToReinvest(_strategySettings.minTokensToReinvest);
updateDevFee(_strategySettings.devFeeBips);
updateReinvestReward(_strategySettings.reinvestRewardBips);
updateFeeCollector(_strategySettings.feeCollector);
updateDevAddr(_strategySettings.dev);
enableDeposits();
transferOwnership(_strategySettings.owner);
}
function deposit(uint256 amount) external virtual;
function depositWithPermit(uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external virtual;
function depositFor(address account, uint256 amount) external virtual;
function withdraw(uint256 amount) external virtual;
function reinvest() external virtual;
function estimateReinvestReward() external view returns (uint256) {
uint256 unclaimedRewards = checkReward();
if (unclaimedRewards >= MIN_TOKENS_TO_REINVEST) {
return (unclaimedRewards * REINVEST_REWARD_BIPS) / BIPS_DIVISOR;
}
return 0;
}
function checkReward() public view virtual returns (uint256);
function rescueDeployedFunds(uint256 minReturnAmountAccepted) external virtual;
function totalDeposits() public view virtual returns (uint256);
function getSharesForDepositTokens(uint256 amount) public view returns (uint256) {
uint256 tDeposits = totalDeposits();
uint256 tSupply = totalSupply;
if (tSupply == 0 || tDeposits == 0) {
return amount;
}
return (amount * tSupply) / tDeposits;
}
function getDepositTokensForShares(uint256 amount) public view returns (uint256) {
uint256 tDeposits = totalDeposits();
uint256 tSupply = totalSupply;
if (tSupply == 0 || tDeposits == 0) {
return 0;
}
return (amount * tDeposits) / tSupply;
}
function revokeAllowance(address token, address spender) external onlyDev {
require(IERC20(token).approve(spender, 0));
}
function disableDeposits() public onlyDev {
require(DEPOSITS_ENABLED);
DEPOSITS_ENABLED = false;
emit DepositsEnabled(false);
}
function updateMinTokensToReinvest(uint256 newValue) public onlyDev {
emit UpdateMinTokensToReinvest(MIN_TOKENS_TO_REINVEST, newValue);
MIN_TOKENS_TO_REINVEST = newValue;
}
function updateDevFee(uint256 newValue) public onlyDev {
require(newValue + REINVEST_REWARD_BIPS <= BIPS_DIVISOR);
emit UpdateDevFee(DEV_FEE_BIPS, newValue);
DEV_FEE_BIPS = newValue;
}
function updateReinvestReward(uint256 newValue) public onlyDev {
require(newValue + DEV_FEE_BIPS <= BIPS_DIVISOR);
emit UpdateReinvestReward(REINVEST_REWARD_BIPS, newValue);
REINVEST_REWARD_BIPS = newValue;
}
function enableDeposits() public onlyOwner {
require(!DEPOSITS_ENABLED);
DEPOSITS_ENABLED = true;
emit DepositsEnabled(true);
}
function updateDevAddr(address newValue) public onlyOwner {
emit UpdateDevAddr(devAddr, newValue);
devAddr = newValue;
}
function updateFeeCollector(address newValue) public onlyOwner {
emit UpdateFeeCollector(feeCollector, newValue);
feeCollector = newValue;
}
function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
require(tokenAmount > 0);
IERC20(tokenAddress).safeTransfer(msg.sender, tokenAmount);
emit Recovered(tokenAddress, tokenAmount);
}
function recoverGas(uint256 amount) external onlyOwner {
require(amount > 0);
payable(msg.sender).transfer(amount);
emit Recovered(address(0), amount);
}
}
{
"compilationTarget": {
"contracts/strategies/arbitrum/wombex/WombexStrategy.sol": "WombexStrategy"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 999
},
"remappings": []
}
[{"inputs":[{"components":[{"internalType":"address","name":"poolDepositor","type":"address"},{"internalType":"address","name":"rewardPool","type":"address"}],"internalType":"struct WombexStrategy.WombexStrategySettings","name":"_wombexStrategySettings","type":"tuple"},{"components":[{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"address[]","name":"rewards","type":"address[]"},{"internalType":"address","name":"simpleRouter","type":"address"}],"internalType":"struct BaseStrategy.BaseStrategySettings","name":"baseStrategySettings","type":"tuple"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"dev","type":"address"},{"internalType":"address","name":"feeCollector","type":"address"},{"internalType":"address","name":"depositToken","type":"address"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"minTokensToReinvest","type":"uint256"},{"internalType":"uint256","name":"devFeeBips","type":"uint256"},{"internalType":"uint256","name":"reinvestRewardBips","type":"uint256"}],"internalType":"struct YakStrategyV3.StrategySettings","name":"_strategySettings","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewardToken","type":"address"}],"name":"AddReward","type":"event"},{"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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newValue","type":"bool"}],"name":"DepositsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalDeposits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"Reinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewardToken","type":"address"}],"name":"RemoveReward","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":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"UpdateDevAddr","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateDevFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"UpdateFeeCollector","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMaxTokensToDepositWithoutReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMinTokensToReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateReinvestReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRouter","type":"address"},{"indexed":false,"internalType":"address","name":"newRouter","type":"address"}],"name":"UpdateRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DEPOSITS_ENABLED","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV_FEE_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TOKENS_TO_REINVEST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REINVEST_REWARD_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"booster","outputs":[{"internalType":"contract IBooster","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculateDepositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculateWithdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","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":"depositWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"estimateReinvestReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getDepositTokensForShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSharesForDepositTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupportedRewardsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"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":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolDepositor","outputs":[{"internalType":"contract IPoolDepositor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"removeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minReturnAmountAccepted","type":"uint256"}],"name":"rescueDeployedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"revokeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPool","outputs":[{"internalType":"contract IWombexRewardPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"simpleRouter","outputs":[{"internalType":"contract ISimpleRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supportedRewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"updateDevAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateDevFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"updateFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMinTokensToReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateReinvestReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"updateRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wombatAsset","outputs":[{"internalType":"contract IWombatAsset","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wombatPool","outputs":[{"internalType":"contract IWombatPool","name":"","type":"address"}],"stateMutability":"view","type":"function"}]