编译器
0.8.15+commit.e14f2714
文件 1 的 28:AccessControl.sol
pragma solidity ^0.8.0;
contract AccessControl {
struct RoleData {
mapping (address => bool) members;
bytes4 adminRole;
}
mapping (bytes4 => RoleData) private _roles;
bytes4 public constant ROOT = 0x00000000;
bytes4 public constant ROOT4146650865 = 0x00000000;
bytes4 public constant LOCK = 0xFFFFFFFF;
bytes4 public constant LOCK8605463013 = 0xFFFFFFFF;
event RoleAdminChanged(bytes4 indexed role, bytes4 indexed newAdminRole);
event RoleGranted(bytes4 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes4 indexed role, address indexed account, address indexed sender);
constructor () {
_grantRole(ROOT, msg.sender);
_setRoleAdmin(LOCK, LOCK);
}
modifier auth() {
require (_hasRole(msg.sig, msg.sender), "Access denied");
_;
}
modifier admin(bytes4 role) {
require (_hasRole(_getRoleAdmin(role), msg.sender), "Only admin");
_;
}
function hasRole(bytes4 role, address account) external view returns (bool) {
return _hasRole(role, account);
}
function getRoleAdmin(bytes4 role) external view returns (bytes4) {
return _getRoleAdmin(role);
}
function setRoleAdmin(bytes4 role, bytes4 adminRole) external virtual admin(role) {
_setRoleAdmin(role, adminRole);
}
function grantRole(bytes4 role, address account) external virtual admin(role) {
_grantRole(role, account);
}
function grantRoles(bytes4[] memory roles, address account) external virtual {
for (uint256 i = 0; i < roles.length; i++) {
require (_hasRole(_getRoleAdmin(roles[i]), msg.sender), "Only admin");
_grantRole(roles[i], account);
}
}
function lockRole(bytes4 role) external virtual admin(role) {
_setRoleAdmin(role, LOCK);
}
function revokeRole(bytes4 role, address account) external virtual admin(role) {
_revokeRole(role, account);
}
function revokeRoles(bytes4[] memory roles, address account) external virtual {
for (uint256 i = 0; i < roles.length; i++) {
require (_hasRole(_getRoleAdmin(roles[i]), msg.sender), "Only admin");
_revokeRole(roles[i], account);
}
}
function renounceRole(bytes4 role, address account) external virtual {
require(account == msg.sender, "Renounce only for self");
_revokeRole(role, account);
}
function _hasRole(bytes4 role, address account) internal view returns (bool) {
return _roles[role].members[account];
}
function _getRoleAdmin(bytes4 role) internal view returns (bytes4) {
return _roles[role].adminRole;
}
function _setRoleAdmin(bytes4 role, bytes4 adminRole) internal virtual {
if (_getRoleAdmin(role) != adminRole) {
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, adminRole);
}
}
function _grantRole(bytes4 role, address account) internal {
if (!_hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, msg.sender);
}
}
function _revokeRole(bytes4 role, address account) internal {
if (_hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, msg.sender);
}
}
}
文件 2 的 28:AddressStringUtil.sol
pragma solidity >=0.5.0;
library AddressStringUtil {
function toAsciiString(address addr, uint256 len) internal pure returns (string memory) {
require(len % 2 == 0 && len > 0 && len <= 40, "AddressStringUtil: INVALID_LEN");
bytes memory s = new bytes(len);
uint256 addrNum = uint256(uint160(addr));
for (uint256 ii = 0; ii < len ; ii +=2) {
uint8 b = uint8(addrNum >> (4 * (38 - ii)));
s[ii] = char(b >> 4);
s[ii + 1] = char(b & 0x0f);
}
return string(s);
}
function char(uint8 b) private pure returns (bytes1 c) {
if (b < 10) {
return bytes1(b + 0x30);
} else {
return bytes1(b + 0x37);
}
}
}
文件 3 的 28:Cast.sol
pragma solidity ^0.8.13;
library Cast {
function b12(bytes32 x) internal pure returns (bytes12 y) {
require(bytes32(y = bytes12(x)) == x, "Cast overflow");
}
function b6(bytes32 x) internal pure returns (bytes6 y) {
require(bytes32(y = bytes6(x)) == x, "Cast overflow");
}
function u256(int256 x) internal pure returns (uint256 y) {
require(x >= 0, "Cast overflow");
y = uint256(x);
}
function i256(uint256 x) internal pure returns (int256 y) {
require(x <= uint256(type(int256).max), "Cast overflow");
y = int256(x);
}
function u128(uint256 x) internal pure returns (uint128 y) {
require(x <= type(uint128).max, "Cast overflow");
y = uint128(x);
}
function u128(int256 x) internal pure returns (uint128 y) {
require(x >= 0, "Cast overflow");
y = uint128(uint256(x));
}
function i128(uint256 x) internal pure returns (int128) {
require(x <= uint256(int256(type(int128).max)), "Cast overflow");
return int128(int256(x));
}
function i128(int256 x) internal pure returns (int128) {
require(x <= type(int128).max, "Cast overflow");
require(x >= type(int128).min, "Cast overflow");
return int128(x);
}
function u112(uint256 x) internal pure returns (uint112 y) {
require(x <= type(uint112).max, "Cast overflow");
y = uint112(x);
}
function u104(uint256 x) internal pure returns (uint104 y) {
require(x <= type(uint104).max, "Cast overflow");
y = uint104(x);
}
function u96(uint256 x) internal pure returns (uint96 y) {
require(x <= type(uint96).max, "Cast overflow");
y = uint96(x);
}
function u32(uint256 x) internal pure returns (uint32 y) {
require(x <= type(uint32).max, "Cast overflow");
y = uint32(x);
}
}
文件 4 的 28:DataTypes.sol
pragma solidity ^0.8.0;
import "./IFYToken.sol";
import "./IOracle.sol";
library DataTypes {
struct Series {
IFYToken fyToken;
bytes6 baseId;
uint32 maturity;
}
struct Debt {
uint96 max;
uint24 min;
uint8 dec;
uint128 sum;
}
struct SpotOracle {
IOracle oracle;
uint32 ratio;
}
struct Vault {
address owner;
bytes6 seriesId;
bytes6 ilkId;
}
struct Balances {
uint128 art;
uint128 ink;
}
struct Auction {
address owner;
uint32 start;
bytes6 baseId;
uint128 ink;
uint128 art;
address auctioneer;
bytes6 ilkId;
bytes6 seriesId;
}
struct Line {
uint32 duration;
uint64 vaultProportion;
uint64 collateralProportion;
}
struct Limits {
uint128 max;
uint128 sum;
}
}
library VRDataTypes {
struct Vault {
address owner;
bytes6 baseId;
bytes6 ilkId;
}
}
文件 5 的 28:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20Metadata.sol";
contract ERC20 is IERC20Metadata {
uint256 internal _totalSupply;
mapping (address => uint256) internal _balanceOf;
mapping (address => mapping (address => uint256)) internal _allowance;
string public override name = "???";
string public override symbol = "???";
uint8 public override decimals = 18;
constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
decimals = decimals_;
}
function totalSupply() external view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address guy) external view virtual override returns (uint256) {
return _balanceOf[guy];
}
function allowance(address owner, address spender) external view virtual override returns (uint256) {
return _allowance[owner][spender];
}
function approve(address spender, uint wad) external virtual override returns (bool) {
return _setAllowance(msg.sender, spender, wad);
}
function transfer(address dst, uint wad) external virtual override returns (bool) {
return _transfer(msg.sender, dst, wad);
}
function transferFrom(address src, address dst, uint wad) external virtual override returns (bool) {
_decreaseAllowance(src, wad);
return _transfer(src, dst, wad);
}
function _transfer(address src, address dst, uint wad) internal virtual returns (bool) {
require(_balanceOf[src] >= wad, "ERC20: Insufficient balance");
unchecked { _balanceOf[src] = _balanceOf[src] - wad; }
_balanceOf[dst] = _balanceOf[dst] + wad;
emit Transfer(src, dst, wad);
return true;
}
function _setAllowance(address owner, address spender, uint wad) internal virtual returns (bool) {
_allowance[owner][spender] = wad;
emit Approval(owner, spender, wad);
return true;
}
function _decreaseAllowance(address src, uint wad) internal virtual returns (bool) {
if (src != msg.sender) {
uint256 allowed = _allowance[src][msg.sender];
if (allowed != type(uint).max) {
require(allowed >= wad, "ERC20: Insufficient approval");
unchecked { _setAllowance(src, msg.sender, allowed - wad); }
}
}
return true;
}
function _mint(address dst, uint wad) internal virtual returns (bool) {
_balanceOf[dst] = _balanceOf[dst] + wad;
_totalSupply = _totalSupply + wad;
emit Transfer(address(0), dst, wad);
return true;
}
function _burn(address src, uint wad) internal virtual returns (bool) {
unchecked {
require(_balanceOf[src] >= wad, "ERC20: Insufficient balance");
_balanceOf[src] = _balanceOf[src] - wad;
_totalSupply = _totalSupply - wad;
emit Transfer(src, address(0), wad);
}
return true;
}
}
文件 6 的 28:ERC20Permit.sol
pragma solidity ^0.8.0;
import "./ERC20.sol";
import "./IERC2612.sol";
abstract contract ERC20Permit is ERC20, IERC2612 {
mapping (address => uint256) public override nonces;
bytes32 public immutable PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 private immutable _DOMAIN_SEPARATOR;
uint256 public immutable deploymentChainId;
constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_, decimals_) {
deploymentChainId = block.chainid;
_DOMAIN_SEPARATOR = _calculateDomainSeparator(block.chainid);
}
function _calculateDomainSeparator(uint256 chainId) private view returns (bytes32) {
return keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes(version())),
chainId,
address(this)
)
);
}
function DOMAIN_SEPARATOR() external view returns (bytes32) {
return block.chainid == deploymentChainId ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(block.chainid);
}
function version() public pure virtual returns(string memory) { return "1"; }
function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external virtual override {
require(deadline >= block.timestamp, "ERC20Permit: expired deadline");
bytes32 hashStruct = keccak256(
abi.encode(
PERMIT_TYPEHASH,
owner,
spender,
amount,
nonces[owner]++,
deadline
)
);
bytes32 hash = keccak256(
abi.encodePacked(
"\x19\x01",
block.chainid == deploymentChainId ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(block.chainid),
hashStruct
)
);
address signer = ecrecover(hash, v, r, s);
require(
signer != address(0) && signer == owner,
"ERC20Permit: invalid signature"
);
_setAllowance(owner, spender, amount);
}
}
文件 7 的 28:ERC20Rewards.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./ERC20Permit.sol";
import "../access/AccessControl.sol";
import "../utils/RevertMsgExtractor.sol";
import "../token/MinimalTransferHelper.sol";
import "../utils/Cast.sol";
contract ERC20Rewards is AccessControl, ERC20Permit {
using MinimalTransferHelper for IERC20;
using Cast for uint256;
event RewardsTokenSet(IERC20 token);
event RewardsSet(uint32 start, uint32 end, uint256 rate);
event RewardsPerTokenUpdated(uint256 accumulated);
event UserRewardsUpdated(address user, uint256 userRewards, uint256 paidRewardPerToken);
event Claimed(address user, address receiver, uint256 claimed);
struct RewardsPeriod {
uint32 start;
uint32 end;
}
struct RewardsPerToken {
uint128 accumulated;
uint32 lastUpdated;
uint96 rate;
}
struct UserRewards {
uint128 accumulated;
uint128 checkpoint;
}
IERC20 public rewardsToken;
RewardsPeriod public rewardsPeriod;
RewardsPerToken public rewardsPerToken;
mapping (address => UserRewards) public rewards;
constructor(string memory name, string memory symbol, uint8 decimals)
ERC20Permit(name, symbol, decimals)
{ }
function earliest(uint32 x, uint32 y) internal pure returns (uint32 z) {
z = (x < y) ? x : y;
}
function setRewardsToken(IERC20 rewardsToken_)
external
auth
{
require(rewardsToken == IERC20(address(0)), "Rewards token already set");
rewardsToken = rewardsToken_;
emit RewardsTokenSet(rewardsToken_);
}
function setRewards(uint32 start, uint32 end, uint96 rate)
external
auth
{
require(
start <= end,
"Incorrect input"
);
require(
rewardsToken != IERC20(address(0)),
"Rewards token not set"
);
require(
block.timestamp.u32() < rewardsPeriod.start || block.timestamp.u32() > rewardsPeriod.end,
"Ongoing rewards"
);
_updateRewardsPerToken();
rewardsPeriod.start = start;
rewardsPeriod.end = end;
rewardsPerToken.lastUpdated = start;
rewardsPerToken.rate = rate;
emit RewardsSet(start, end, rate);
}
function _updateRewardsPerToken() internal {
RewardsPerToken memory rewardsPerToken_ = rewardsPerToken;
RewardsPeriod memory rewardsPeriod_ = rewardsPeriod;
uint256 totalSupply_ = _totalSupply;
if (block.timestamp.u32() < rewardsPeriod_.start) return;
uint32 end = earliest(block.timestamp.u32(), rewardsPeriod_.end);
uint256 unaccountedTime = end - rewardsPerToken_.lastUpdated;
if (unaccountedTime == 0) return;
if (totalSupply_ != 0) rewardsPerToken_.accumulated = (rewardsPerToken_.accumulated + 1e18 * unaccountedTime * rewardsPerToken_.rate / totalSupply_).u128();
rewardsPerToken_.lastUpdated = end;
rewardsPerToken = rewardsPerToken_;
emit RewardsPerTokenUpdated(rewardsPerToken_.accumulated);
}
function _updateUserRewards(address user) internal returns (uint128) {
UserRewards memory userRewards_ = rewards[user];
RewardsPerToken memory rewardsPerToken_ = rewardsPerToken;
userRewards_.accumulated = (userRewards_.accumulated + _balanceOf[user] * (rewardsPerToken_.accumulated - userRewards_.checkpoint) / 1e18).u128();
userRewards_.checkpoint = rewardsPerToken_.accumulated;
rewards[user] = userRewards_;
emit UserRewardsUpdated(user, userRewards_.accumulated, userRewards_.checkpoint);
return userRewards_.accumulated;
}
function _mint(address dst, uint256 wad)
internal virtual override
returns (bool)
{
_updateRewardsPerToken();
_updateUserRewards(dst);
return super._mint(dst, wad);
}
function _burn(address src, uint256 wad)
internal virtual override
returns (bool)
{
_updateRewardsPerToken();
_updateUserRewards(src);
return super._burn(src, wad);
}
function _transfer(address src, address dst, uint wad) internal virtual override returns (bool) {
_updateRewardsPerToken();
_updateUserRewards(src);
_updateUserRewards(dst);
return super._transfer(src, dst, wad);
}
function claim(address to)
external
returns (uint256 claiming)
{
claiming = _claim(msg.sender, to);
}
function remit(address user)
external
returns (uint256 claiming)
{
claiming = _claim(user, user);
}
function _claim(address from, address to)
internal
returns (uint256 claiming)
{
_updateRewardsPerToken();
claiming = _updateUserRewards(from);
rewards[from].accumulated = 0;
rewardsToken.safeTransfer(to, claiming);
emit Claimed(from, to, claiming);
}
}
文件 8 的 28:ICauldron.sol
pragma solidity ^0.8.0;
import "./IFYToken.sol";
import "./IOracle.sol";
import "./DataTypes.sol";
interface ICauldron {
function lendingOracles(bytes6 baseId) external view returns (IOracle);
function vaults(bytes12 vault)
external
view
returns (DataTypes.Vault memory);
function series(bytes6 seriesId)
external
view
returns (DataTypes.Series memory);
function assets(bytes6 assetsId) external view returns (address);
function balances(bytes12 vault)
external
view
returns (DataTypes.Balances memory);
function ilks(bytes6 seriesId, bytes6 assetId)
external
view
returns (bool);
function debt(bytes6 baseId, bytes6 ilkId)
external
view
returns (DataTypes.Debt memory);
function spotOracles(bytes6 baseId, bytes6 ilkId)
external
view
returns (DataTypes.SpotOracle memory);
function build(
address owner,
bytes12 vaultId,
bytes6 seriesId,
bytes6 ilkId
) external returns (DataTypes.Vault memory);
function destroy(bytes12 vault) external;
function tweak(
bytes12 vaultId,
bytes6 seriesId,
bytes6 ilkId
) external returns (DataTypes.Vault memory);
function give(bytes12 vaultId, address receiver)
external
returns (DataTypes.Vault memory);
function stir(
bytes12 from,
bytes12 to,
uint128 ink,
uint128 art
) external returns (DataTypes.Balances memory, DataTypes.Balances memory);
function pour(
bytes12 vaultId,
int128 ink,
int128 art
) external returns (DataTypes.Balances memory);
function roll(
bytes12 vaultId,
bytes6 seriesId,
int128 art
) external returns (DataTypes.Vault memory, DataTypes.Balances memory);
function slurp(
bytes12 vaultId,
uint128 ink,
uint128 art
) external returns (DataTypes.Balances memory);
function debtFromBase(bytes6 seriesId, uint128 base)
external
returns (uint128 art);
function debtToBase(bytes6 seriesId, uint128 art)
external
returns (uint128 base);
function mature(bytes6 seriesId) external;
function accrual(bytes6 seriesId) external returns (uint256);
function level(bytes12 vaultId) external returns (int256);
}
文件 9 的 28:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
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);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 10 的 28:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 11 的 28:IERC2612.sol
pragma solidity ^0.8.0;
interface IERC2612 {
function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
function nonces(address owner) external view returns (uint256);
}
文件 12 的 28:IERC5095.sol
pragma solidity >=0.8.13;
import "@yield-protocol/utils-v2/src/token/IERC20.sol";
interface IERC5095 is IERC20 {
function underlying() external view returns (address underlyingAddress);
function maturity() external view returns (uint256 timestamp);
function convertToUnderlying(uint256 principalAmount) external returns (uint256 underlyingAmount);
function convertToPrincipal(uint256 underlyingAmount) external returns (uint256 principalAmount);
function maxRedeem(address holder) external view returns (uint256 maxPrincipalAmount);
function previewRedeem(uint256 principalAmount) external returns (uint256 underlyingAmount);
function redeem(uint256 principalAmount, address to, address from) external returns (uint256 underlyingAmount);
function maxWithdraw(address holder) external returns (uint256 maxUnderlyingAmount);
function previewWithdraw(uint256 underlyingAmount) external returns (uint256 principalAmount);
function withdraw(uint256 underlyingAmount, address to, address from) external returns (uint256 principalAmount);
}
文件 13 的 28:IFYToken.sol
pragma solidity ^0.8.0;
import "./IERC5095.sol";
import "./IJoin.sol";
import "./IOracle.sol";
interface IFYToken is IERC5095 {
function oracle() view external returns (IOracle);
function join() view external returns (IJoin);
function underlying() view external returns (address);
function underlyingId() view external returns (bytes6);
function maturity() view external returns (uint256);
function chiAtMaturity() view external returns (uint256);
function mature() external;
function mintWithUnderlying(address to, uint256 amount) external;
function redeem(address to, uint256 amount) external returns (uint256);
function mint(address to, uint256 fyTokenAmount) external;
function burn(address from, uint256 fyTokenAmount) external;
}
文件 14 的 28:IJoin.sol
pragma solidity ^0.8.0;
import "@yield-protocol/utils-v2/src/token/IERC20.sol";
interface IJoin {
function asset() external view returns (address);
function storedBalance() external view returns (uint256);
function join(address user, uint128 wad) external returns (uint128);
function exit(address user, uint128 wad) external returns (uint128);
function retrieve(IERC20 token, address to) external;
}
文件 15 的 28:ILadle.sol
pragma solidity ^0.8.0;
import "../Router.sol";
import "./IJoin.sol";
import "./ICauldron.sol";
import "./IFYToken.sol";
import "./IOracle.sol";
import "@yield-protocol/utils-v2/src/interfaces/IWETH9.sol";
import "@yield-protocol/yieldspace-tv/src/interfaces/IPool.sol";
interface ILadle {
function cauldron()
external view
returns(ICauldron);
function router()
external view
returns(Router);
function weth()
external view
returns(IWETH9);
function borrowingFee()
external view
returns(uint256);
function joins(bytes6)
external view
returns (IJoin);
function pools(bytes6)
external view
returns (address);
function modules(address)
external view
returns (bool);
function integrations(address)
external view
returns (bool);
function tokens(address)
external view
returns (bool);
function addIntegration(address integration, bool set)
external;
function addToken(address token, bool set)
external;
function addJoin(bytes6 assetId, IJoin join)
external;
function addPool(bytes6 seriesId, IPool pool)
external;
function addModule(address module, bool set)
external;
function setFee(uint256 fee)
external;
function batch(bytes[] calldata calls)
external payable
returns(bytes[] memory results);
function route(address integration, bytes calldata data)
external payable
returns (bytes memory result);
function moduleCall(address module, bytes calldata data)
external payable
returns (bytes memory result);
function forwardPermit(IERC2612 token, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external payable;
function forwardDaiPermit(IERC20 token, address spender, uint256 nonce, uint256 deadline, bool allowed, uint8 v, bytes32 r, bytes32 s)
external payable;
function transfer(IERC20 token, address receiver, uint128 wad)
external payable;
function retrieve(IERC20 token, address to)
external payable
returns (uint256 amount);
function joinEther(bytes6 etherId)
external payable
returns (uint256 ethTransferred);
function exitEther(address to)
external payable
returns (uint256 ethTransferred);
function build(bytes6 seriesId, bytes6 ilkId, uint8 salt)
external payable
returns(bytes12, DataTypes.Vault memory);
function tweak(bytes12 vaultId_, bytes6 seriesId, bytes6 ilkId)
external payable
returns(DataTypes.Vault memory vault);
function give(bytes12 vaultId_, address receiver)
external payable
returns(DataTypes.Vault memory vault);
function destroy(bytes12 vaultId_)
external payable;
function stir(bytes12 from, bytes12 to, uint128 ink, uint128 art)
external payable;
function pour(bytes12 vaultId_, address to, int128 ink, int128 art)
external payable;
function serve(bytes12 vaultId_, address to, uint128 ink, uint128 base, uint128 max)
external payable
returns (uint128 art);
function close(bytes12 vaultId_, address to, int128 ink, int128 art)
external payable
returns (uint128 base);
function repay(bytes12 vaultId_, address to, int128 ink, uint128 min)
external payable
returns (uint128 art);
function repayVault(bytes12 vaultId_, address to, int128 ink, uint128 max)
external payable
returns (uint128 base);
function roll(bytes12 vaultId_, bytes6 newSeriesId, uint8 loan, uint128 max)
external payable
returns (DataTypes.Vault memory vault, uint128 newDebt);
function repayFromLadle(bytes12 vaultId_, address to)
external payable
returns (uint256 repaid);
function closeFromLadle(bytes12 vaultId_, address to)
external payable
returns (uint256 repaid);
function redeem(bytes6 seriesId, address to, uint256 wad)
external payable
returns (uint256);
}
文件 16 的 28:IMaturingToken.sol
pragma solidity >=0.8.15;
import "@yield-protocol/utils-v2/src/token/IERC20.sol";
interface IMaturingToken is IERC20 {
function maturity() external view returns (uint256);
}
文件 17 的 28:IOracle.sol
pragma solidity ^0.8.0;
interface IOracle {
function peek(
bytes32 base,
bytes32 quote,
uint256 amount
) external view returns (uint256 value, uint256 updateTime);
function get(
bytes32 base,
bytes32 quote,
uint256 amount
) external returns (uint256 value, uint256 updateTime);
}
文件 18 的 28:IPool.sol
pragma solidity >= 0.8.0;
import "@yield-protocol/utils-v2/src/token/IERC20.sol";
import "@yield-protocol/utils-v2/src/token/IERC2612.sol";
import {IMaturingToken} from "./IMaturingToken.sol";
import {IERC20Metadata} from "@yield-protocol/utils-v2/src/token/ERC20.sol";
interface IPool is IERC20, IERC2612 {
function baseToken() external view returns(IERC20Metadata);
function base() external view returns(IERC20);
function burn(address baseTo, address fyTokenTo, uint256 minRatio, uint256 maxRatio) external returns (uint256, uint256, uint256);
function burnForBase(address to, uint256 minRatio, uint256 maxRatio) external returns (uint256, uint256);
function buyBase(address to, uint128 baseOut, uint128 max) external returns(uint128);
function buyBasePreview(uint128 baseOut) external view returns(uint128);
function buyFYToken(address to, uint128 fyTokenOut, uint128 max) external returns(uint128);
function buyFYTokenPreview(uint128 fyTokenOut) external view returns(uint128);
function currentCumulativeRatio() external view returns (uint256 currentCumulativeRatio_, uint256 blockTimestampCurrent);
function cumulativeRatioLast() external view returns (uint256);
function fyToken() external view returns(IMaturingToken);
function g1() external view returns(int128);
function g2() external view returns(int128);
function getC() external view returns (int128);
function getCurrentSharePrice() external view returns (uint256);
function getCache() external view returns (uint104 baseCached, uint104 fyTokenCached, uint32 blockTimestampLast, uint16 g1Fee_);
function getBaseBalance() external view returns(uint128);
function getFYTokenBalance() external view returns(uint128);
function getSharesBalance() external view returns(uint128);
function init(address to) external returns (uint256, uint256, uint256);
function maturity() external view returns(uint32);
function mint(address to, address remainder, uint256 minRatio, uint256 maxRatio) external returns (uint256, uint256, uint256);
function mu() external view returns (int128);
function mintWithBase(address to, address remainder, uint256 fyTokenToBuy, uint256 minRatio, uint256 maxRatio) external returns (uint256, uint256, uint256);
function retrieveBase(address to) external returns(uint128 retrieved);
function retrieveFYToken(address to) external returns(uint128 retrieved);
function retrieveShares(address to) external returns(uint128 retrieved);
function scaleFactor() external view returns(uint96);
function sellBase(address to, uint128 min) external returns(uint128);
function sellBasePreview(uint128 baseIn) external view returns(uint128);
function sellFYToken(address to, uint128 min) external returns(uint128);
function sellFYTokenPreview(uint128 fyTokenIn) external view returns(uint128);
function setFees(uint16 g1Fee_) external;
function sharesToken() external view returns(IERC20Metadata);
function ts() external view returns(int128);
function wrap(address receiver) external returns (uint256 shares);
function wrapPreview(uint256 assets) external view returns (uint256 shares);
function unwrap(address receiver) external returns (uint256 assets);
function unwrapPreview(uint256 shares) external view returns (uint256 assets);
function maxFYTokenIn() external view returns (uint128) ;
function maxFYTokenOut() external view returns (uint128) ;
function maxBaseIn() external view returns (uint128) ;
function maxBaseOut() external view returns (uint128);
function invariant() external view returns (uint128);
}
文件 19 的 28:IStrategy.sol
pragma solidity >=0.8.13;
import {IStrategyMigrator} from "./IStrategyMigrator.sol";
import {IERC20} from "@yield-protocol/utils-v2/src/token/IERC20.sol";
import {IFYToken} from "@yield-protocol/vault-v2/src/interfaces/IFYToken.sol";
import {ICauldron} from "@yield-protocol/vault-v2/src/interfaces/ICauldron.sol";
import {ILadle} from "@yield-protocol/vault-v2/src/interfaces/ILadle.sol";
import {IPool} from "@yield-protocol/yieldspace-tv/src/interfaces/IPool.sol";
interface IStrategy is IStrategyMigrator {
enum State {DEPLOYED, DIVESTED, INVESTED, EJECTED, DRAINED}
function state() external view returns(State);
function base() external view returns(IERC20);
function fyToken() external view returns(IFYToken);
function pool() external view returns(IPool);
function cached() external view returns(uint256);
function fyTokenCached() external view returns(uint256);
function init(address to)
external
returns (uint256 baseIn, uint256 fyTokenIn, uint256 minted);
function invest(IPool pool_)
external
returns (uint256 poolTokensObtained);
function divest()
external
returns (uint256 baseObtained);
function eject()
external
returns (uint256 baseObtained, uint256 fyTokenObtained);
function buyFYToken(address fyTokenTo, address baseTo)
external
returns (uint256 soldFYToken, uint256 returnedBase);
function restart()
external
returns (uint256 baseIn);
function mint(address to)
external
returns (uint256 minted);
function burn(address to)
external
returns (uint256 poolTokensObtained);
function mintDivested(address to)
external
returns (uint256 minted);
function burnDivested(address baseTo)
external
returns (uint256 baseObtained);
function rewardsToken() external view returns(IERC20);
function rewardsPeriod() external view returns(uint32 start, uint32 end);
function rewardsPerToken() external view returns(uint128 accumulated, uint32 lastUpdated, uint96 rate);
function rewards(address user) external view returns(uint128 accumulatedUserStart, uint128 accumulatedCheckpoint);
function setRewardsToken(IERC20 rewardsToken_)
external;
function setRewards(uint32 start, uint32 end, uint96 rate)
external;
function claim(address to)
external
returns (uint256 claiming);
function remit(address user)
external
returns (uint256 claiming);
}
文件 20 的 28:IStrategyMigrator.sol
pragma solidity ^0.8.13;
import {IFYToken} from "@yield-protocol/vault-v2/src/interfaces/IFYToken.sol";
import {IERC20} from "@yield-protocol/utils-v2/src/token/IERC20.sol";
interface IStrategyMigrator is IERC20 {
function base() external view returns(IERC20);
function fyToken() external view returns(IFYToken);
function init(address) external returns (uint256, uint256, uint256);
function burn(address, address, uint256, uint256) external returns (uint256, uint256, uint256);
}
文件 21 的 28:IWETH9.sol
import "../token/IERC20.sol";
pragma solidity ^0.8.0;
interface IWETH9 is IERC20 {
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
function deposit() external payable;
function withdraw(uint wad) external;
}
文件 22 的 28:IsContract.sol
pragma solidity ^0.8.0;
library IsContract {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
}
文件 23 的 28:MinimalTransferHelper.sol
pragma solidity >=0.6.0;
import "./IERC20.sol";
import "../utils/RevertMsgExtractor.sol";
library MinimalTransferHelper {
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
if (!(success && (data.length == 0 || abi.decode(data, (bool))))) revert(RevertMsgExtractor.getRevertMsg(data));
}
}
文件 24 的 28:RevertMsgExtractor.sol
pragma solidity >=0.6.0;
library RevertMsgExtractor {
function getRevertMsg(bytes memory returnData)
internal pure
returns (string memory)
{
if (returnData.length < 68) return "Transaction reverted silently";
assembly {
returnData := add(returnData, 0x04)
}
return abi.decode(returnData, (string));
}
}
文件 25 的 28:Router.sol
pragma solidity >=0.8.13;
import "@yield-protocol/utils-v2/src/utils/RevertMsgExtractor.sol";
import "@yield-protocol/utils-v2/src/utils/IsContract.sol";
contract Router {
using IsContract for address;
address immutable public owner;
constructor () {
owner = msg.sender;
}
function route(address target, bytes calldata data)
external payable
returns (bytes memory result)
{
require(msg.sender == owner, "Only owner");
require(target.isContract(), "Target is not a contract");
bool success;
(success, result) = target.call(data);
if (!success) revert(RevertMsgExtractor.getRevertMsg(result));
}
}
文件 26 的 28:SafeERC20Namer.sol
pragma solidity >=0.5.0;
import "../token/IERC20Metadata.sol";
import "../utils/AddressStringUtil.sol";
library SafeERC20Namer {
function bytes32ToString(bytes32 x) private pure returns (string memory) {
bytes memory bytesString = new bytes(32);
uint256 charCount = 0;
for (uint256 j = 0; j < 32; j++) {
bytes1 char = x[j];
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (uint256 j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
function parseStringData(bytes memory b) private pure returns (string memory) {
uint256 charCount = 0;
for (uint256 i = 32; i < 64; i++) {
charCount <<= 8;
charCount += uint8(b[i]);
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (uint256 i = 0; i < charCount; i++) {
bytesStringTrimmed[i] = b[i + 64];
}
return string(bytesStringTrimmed);
}
function addressToName(address token) private pure returns (string memory) {
return AddressStringUtil.toAsciiString(token, 40);
}
function addressToSymbol(address token) private pure returns (string memory) {
return AddressStringUtil.toAsciiString(token, 6);
}
function callAndParseStringReturn(address token, bytes4 selector) private view returns (string memory) {
(bool success, bytes memory data) = token.staticcall(abi.encodeWithSelector(selector));
if (!success || data.length == 0) {
return "";
}
if (data.length == 32) {
bytes32 decoded = abi.decode(data, (bytes32));
return bytes32ToString(decoded);
} else if (data.length > 64) {
return abi.decode(data, (string));
}
return "";
}
function tokenSymbol(address token) public view returns (string memory) {
string memory symbol = callAndParseStringReturn(token, IERC20Metadata.symbol.selector);
if (bytes(symbol).length == 0) {
return addressToSymbol(token);
}
return symbol;
}
function tokenName(address token) public view returns (string memory) {
string memory name = callAndParseStringReturn(token, IERC20Metadata.name.selector);
if (bytes(name).length == 0) {
return addressToName(token);
}
return name;
}
function tokenDecimals(address token) public view returns (uint8) {
(bool success, bytes memory data) = token.staticcall(abi.encodeWithSelector(IERC20Metadata.decimals.selector));
return success && data.length == 32 ? abi.decode(data, (uint8)) : 0;
}
}
文件 27 的 28:Strategy.sol
pragma solidity >=0.8.13;
import { IStrategy } from "./interfaces/IStrategy.sol";
import { StrategyMigrator } from "./StrategyMigrator.sol";
import { AccessControl } from "@yield-protocol/utils-v2/src/access/AccessControl.sol";
import { SafeERC20Namer } from "@yield-protocol/utils-v2/src/token/SafeERC20Namer.sol";
import { MinimalTransferHelper } from "@yield-protocol/utils-v2/src/token/MinimalTransferHelper.sol";
import { IERC20 } from "@yield-protocol/utils-v2/src/token/IERC20.sol";
import { ERC20Rewards } from "@yield-protocol/utils-v2/src/token/ERC20Rewards.sol";
import { IFYToken } from "@yield-protocol/vault-v2/src/interfaces/IFYToken.sol";
import { IPool } from "@yield-protocol/yieldspace-tv/src/interfaces/IPool.sol";
contract Strategy is AccessControl, ERC20Rewards, StrategyMigrator {
enum State {DEPLOYED, DIVESTED, INVESTED, EJECTED, DRAINED}
using MinimalTransferHelper for IERC20;
using MinimalTransferHelper for IFYToken;
using MinimalTransferHelper for IPool;
event Invested(address indexed pool, uint256 baseInvested, uint256 lpTokensObtained);
event Divested(address indexed pool, uint256 lpTokenDivested, uint256 baseObtained);
event Ejected(address indexed pool, uint256 lpTokenDivested, uint256 baseObtained, uint256 fyTokenObtained);
event Drained(address indexed pool, uint256 lpTokenDivested);
event SoldFYToken(uint256 soldFYToken, uint256 returnedBase);
State public state;
IPool public pool;
uint256 public baseCached;
uint256 public poolCached;
uint256 public fyTokenCached;
constructor(string memory name_, string memory symbol_, IFYToken fyToken_)
ERC20Rewards(name_, symbol_, SafeERC20Namer.tokenDecimals(address(fyToken_)))
StrategyMigrator(
IERC20(fyToken_.underlying()),
fyToken_)
{}
modifier isState(State target) {
require (
target == state,
"Not allowed in this state"
);
_;
}
function _transition(State target, IPool pool_) internal {
if (target == State.INVESTED) {
pool = pool_;
fyToken = IFYToken(address(pool_.fyToken()));
maturity = pool_.maturity();
} else if (target == State.DIVESTED) {
delete fyToken;
delete maturity;
delete pool;
} else if (target == State.EJECTED) {
delete maturity;
delete pool;
} else if (target == State.DRAINED) {
delete maturity;
delete pool;
}
state = target;
}
function _transition(State target) internal {
require (target != State.INVESTED, "Must provide a pool");
_transition(target, IPool(address(0)));
}
function init(address to)
external
override
auth
returns (uint256 baseIn, uint256 fyTokenIn, uint256 minted)
{
fyTokenIn = 0;
baseIn = minted = _init(to);
}
function _init(address to)
internal
isState(State.DEPLOYED)
returns (uint256 minted)
{
delete fyToken;
baseCached = minted = base.balanceOf(address(this));
require (minted > 0, "Not enough base in");
_mint(to, minted);
_transition(State.DIVESTED);
}
function invest(IPool pool_)
external
auth
isState(State.DIVESTED)
returns (uint256 poolTokensObtained)
{
IFYToken fyToken_ = IFYToken(address(pool_.fyToken()));
uint256 baseCached_ = baseCached;
require(base == pool_.base(), "Mismatched base");
delete baseCached;
base.safeTransfer(address(pool_), baseCached_);
(,, poolTokensObtained) = pool_.init(address(this));
poolCached = poolTokensObtained;
fyToken = fyToken_;
maturity = pool_.maturity();
pool = pool_;
_transition(State.INVESTED, pool_);
emit Invested(address(pool_), baseCached_, poolTokensObtained);
}
function divest()
external
isState(State.INVESTED)
returns (uint256 baseObtained)
{
IPool pool_ = pool;
IFYToken fyToken_ = fyToken;
require (uint32(block.timestamp) >= maturity, "Only after maturity");
uint256 toDivest = pool_.balanceOf(address(this));
delete poolCached;
pool_.safeTransfer(address(pool_), toDivest);
(, uint256 baseFromBurn, uint256 fyTokenFromBurn) = pool_.burn(address(this), address(this), 0, type(uint256).max);
uint256 baseFromRedeem = fyToken_.redeem(address(this), fyTokenFromBurn);
baseCached = base.balanceOf(address(this));
_transition(State.DIVESTED, pool_);
emit Divested(address(pool_), toDivest, baseObtained = baseFromBurn + baseFromRedeem);
}
function eject()
external
auth
isState(State.INVESTED)
returns (uint256 baseReceived, uint256 fyTokenReceived)
{
IPool pool_ = pool;
uint256 toDivest = pool_.balanceOf(address(this));
delete poolCached;
try this.burnPoolTokens(pool_, toDivest) returns (uint256 baseReceived_, uint256 fyTokenReceived_) {
baseCached = baseReceived = baseReceived_;
fyTokenCached = fyTokenReceived = fyTokenReceived_;
if (fyTokenReceived > 0) {
_transition(State.EJECTED, pool_);
emit Ejected(address(pool_), toDivest, baseReceived, fyTokenReceived);
} else {
_transition(State.DIVESTED, pool_);
emit Divested(address(pool_), toDivest, baseReceived);
}
} catch {
pool_.safeTransfer(msg.sender, toDivest);
_transition(State.DRAINED, pool_);
emit Drained(address(pool_), toDivest);
}
}
function burnPoolTokens(IPool pool_, uint256 poolTokens)
external
returns (uint256 baseReceived, uint256 fyTokenReceived)
{
require (msg.sender == address(this), "Unauthorized");
pool_.safeTransfer(address(pool_), poolTokens);
uint256 baseBalance = base.balanceOf(address(this));
uint256 fyTokenBalance = fyToken.balanceOf(address(this));
(, baseReceived, fyTokenReceived) = pool_.burn(address(this), address(this), 0, type(uint256).max);
require(base.balanceOf(address(this)) - baseBalance == baseReceived, "Burn failed - base");
require(fyToken.balanceOf(address(this)) - fyTokenBalance == fyTokenReceived, "Burn failed - fyToken");
}
function buyFYToken(address fyTokenTo, address baseTo)
external
isState(State.EJECTED)
returns (uint256 soldFYToken, uint256 returnedBase)
{
IFYToken fyToken_ = fyToken;
uint256 baseCached_ = baseCached;
uint256 fyTokenCached_ = fyTokenCached;
uint256 baseIn = base.balanceOf(address(this)) - baseCached_;
(soldFYToken, returnedBase) = baseIn > fyTokenCached_ ? (fyTokenCached_, baseIn - fyTokenCached_) : (baseIn, 0);
baseCached = baseCached_ + soldFYToken;
fyTokenCached = fyTokenCached_ -= soldFYToken;
if (fyTokenCached_ == 0) {
_transition(State.DIVESTED);
emit Divested(address(0), 0, 0);
}
fyToken_.safeTransfer(fyTokenTo, soldFYToken);
if (soldFYToken < baseIn) {
base.safeTransfer(baseTo, baseIn - soldFYToken);
}
emit SoldFYToken(soldFYToken, returnedBase);
}
function restart()
external
auth
isState(State.DRAINED)
returns (uint256 baseIn)
{
require((baseCached = baseIn = base.balanceOf(address(this))) > 0, "No base to restart");
_transition(State.DIVESTED);
emit Divested(address(0), 0, 0);
}
function call(address target, bytes calldata data) external auth returns (bytes memory) {
(bool success, bytes memory returndata) = target.call(data);
require(success, "Call failed");
return returndata;
}
function mint(address to)
external
isState(State.INVESTED)
returns (uint256 minted)
{
IPool pool_ = pool;
uint256 poolCached_ = poolCached;
uint256 deposit = pool_.balanceOf(address(this)) - poolCached_;
poolCached = poolCached_ + deposit;
minted = _totalSupply * deposit / poolCached_;
_mint(to, minted);
}
function burn(address to)
external
isState(State.INVESTED)
returns (uint256 poolTokensObtained)
{
IPool pool_ = pool;
uint256 poolCached_ = poolCached;
uint256 totalSupply_ = _totalSupply;
uint256 burnt = _balanceOf[address(this)];
_burn(address(this), burnt);
poolTokensObtained = poolCached_ * burnt / totalSupply_;
pool_.safeTransfer(address(to), poolTokensObtained);
poolCached = poolCached_ - poolTokensObtained;
}
function mintDivested(address to)
external
isState(State.DIVESTED)
returns (uint256 minted)
{
uint256 baseCached_ = baseCached;
uint256 deposit = base.balanceOf(address(this)) - baseCached_;
baseCached = baseCached_ + deposit;
minted = _totalSupply * deposit / baseCached_;
_mint(to, minted);
}
function burnDivested(address to)
external
isState(State.DIVESTED)
returns (uint256 baseObtained)
{
uint256 baseCached_ = baseCached;
uint256 burnt = _balanceOf[address(this)];
baseObtained = baseCached_ * burnt / _totalSupply;
baseCached = baseCached_ - baseObtained;
_burn(address(this), burnt);
base.safeTransfer(to, baseObtained);
}
}
文件 28 的 28:StrategyMigrator.sol
pragma solidity ^0.8.13;
import {IStrategyMigrator} from "./interfaces/IStrategyMigrator.sol";
import {IFYToken} from "@yield-protocol/vault-v2/src/interfaces/IFYToken.sol";
import {IERC20} from "@yield-protocol/utils-v2/src/token/IERC20.sol";
abstract contract StrategyMigrator is IStrategyMigrator {
IERC20 public immutable base;
IFYToken public fyToken;
uint32 public maturity;
constructor(IERC20 base_, IFYToken fyToken_) {
base = base_;
fyToken = fyToken_;
}
function init(address)
external
virtual
returns (uint256, uint256, uint256)
{
return (0, 0, 0);
}
function burn(address, address, uint256, uint256)
external
virtual
returns (uint256, uint256, uint256)
{
revert();
}
}
{
"compilationTarget": {
"@yield-protocol/strategy-v2/src/Strategy.sol": "Strategy"
},
"evmVersion": "london",
"libraries": {
"@yield-protocol/utils-v2/src/token/SafeERC20Namer.sol:SafeERC20Namer": "0x39bb9cbe0221d769e30bd08d185842065bce1706"
},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 100
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IFYToken","name":"fyToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimed","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenDivested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseObtained","type":"uint256"}],"name":"Divested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenDivested","type":"uint256"}],"name":"Drained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenDivested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseObtained","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fyTokenObtained","type":"uint256"}],"name":"Ejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"baseInvested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpTokensObtained","type":"uint256"}],"name":"Invested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"accumulated","type":"uint256"}],"name":"RewardsPerTokenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"start","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"end","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"RewardsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"}],"name":"RewardsTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"role","type":"bytes4"},{"indexed":true,"internalType":"bytes4","name":"newAdminRole","type":"bytes4"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"role","type":"bytes4"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"role","type":"bytes4"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"soldFYToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnedBase","type":"uint256"}],"name":"SoldFYToken","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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"userRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paidRewardPerToken","type":"uint256"}],"name":"UserRewardsUpdated","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOCK","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOCK8605463013","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT4146650865","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"base","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"poolTokensObtained","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"burn","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burnDivested","outputs":[{"internalType":"uint256","name":"baseObtained","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool_","type":"address"},{"internalType":"uint256","name":"poolTokens","type":"uint256"}],"name":"burnPoolTokens","outputs":[{"internalType":"uint256","name":"baseReceived","type":"uint256"},{"internalType":"uint256","name":"fyTokenReceived","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fyTokenTo","type":"address"},{"internalType":"address","name":"baseTo","type":"address"}],"name":"buyFYToken","outputs":[{"internalType":"uint256","name":"soldFYToken","type":"uint256"},{"internalType":"uint256","name":"returnedBase","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"call","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"claim","outputs":[{"internalType":"uint256","name":"claiming","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"divest","outputs":[{"internalType":"uint256","name":"baseObtained","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eject","outputs":[{"internalType":"uint256","name":"baseReceived","type":"uint256"},{"internalType":"uint256","name":"fyTokenReceived","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fyToken","outputs":[{"internalType":"contract IFYToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fyTokenCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4[]","name":"roles","type":"bytes4[]"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"init","outputs":[{"internalType":"uint256","name":"baseIn","type":"uint256"},{"internalType":"uint256","name":"fyTokenIn","type":"uint256"},{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool_","type":"address"}],"name":"invest","outputs":[{"internalType":"uint256","name":"poolTokensObtained","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"lockRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintDivested","outputs":[{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"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":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"remit","outputs":[{"internalType":"uint256","name":"claiming","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restart","outputs":[{"internalType":"uint256","name":"baseIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4[]","name":"roles","type":"bytes4[]"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint128","name":"accumulated","type":"uint128"},{"internalType":"uint128","name":"checkpoint","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerToken","outputs":[{"internalType":"uint128","name":"accumulated","type":"uint128"},{"internalType":"uint32","name":"lastUpdated","type":"uint32"},{"internalType":"uint96","name":"rate","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPeriod","outputs":[{"internalType":"uint32","name":"start","type":"uint32"},{"internalType":"uint32","name":"end","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"start","type":"uint32"},{"internalType":"uint32","name":"end","type":"uint32"},{"internalType":"uint96","name":"rate","type":"uint96"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"rewardsToken_","type":"address"}],"name":"setRewardsToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"bytes4","name":"adminRole","type":"bytes4"}],"name":"setRoleAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Strategy.State","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"wad","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":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]