文件 1 的 19: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 的 19: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 的 19:CastU256U128.sol
pragma solidity ^0.8.0;
library CastU256U128 {
function u128(uint256 x) internal pure returns (uint128 y) {
require (x <= type(uint128).max, "Cast overflow");
y = uint128(x);
}
}
文件 4 的 19:CastU256U32.sol
pragma solidity ^0.8.0;
library CastU256U32 {
function u32(uint256 x) internal pure returns (uint32 y) {
require (x <= type(uint32).max, "Cast overflow");
y = uint32(x);
}
}
文件 5 的 19:Constants.sol
pragma solidity 0.8.6;
contract Constants {
bytes32 constant CHI = "CHI";
bytes32 constant RATE = "RATE";
bytes6 constant ETH = "00";
}
文件 6 的 19: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;
}
}
文件 7 的 19: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);
}
}
文件 8 的 19:FYToken.sol
pragma solidity 0.8.6;
import "erc3156/contracts/interfaces/IERC3156FlashBorrower.sol";
import "erc3156/contracts/interfaces/IERC3156FlashLender.sol";
import "@yield-protocol/utils-v2/contracts/token/ERC20Permit.sol";
import "@yield-protocol/utils-v2/contracts/token/SafeERC20Namer.sol";
import "@yield-protocol/vault-interfaces/IFYToken.sol";
import "@yield-protocol/vault-interfaces/IJoin.sol";
import "@yield-protocol/vault-interfaces/IOracle.sol";
import "@yield-protocol/utils-v2/contracts/access/AccessControl.sol";
import "@yield-protocol/utils-v2/contracts/math/WMul.sol";
import "@yield-protocol/utils-v2/contracts/math/WDiv.sol";
import "@yield-protocol/utils-v2/contracts/cast/CastU256U128.sol";
import "@yield-protocol/utils-v2/contracts/cast/CastU256U32.sol";
import "./constants/Constants.sol";
contract FYToken is IFYToken, IERC3156FlashLender, AccessControl(), ERC20Permit, Constants {
using WMul for uint256;
using WDiv for uint256;
using CastU256U128 for uint256;
using CastU256U32 for uint256;
event Point(bytes32 indexed param, address value);
event FlashFeeFactorSet(uint256 indexed fee);
event SeriesMatured(uint256 chiAtMaturity);
event Redeemed(address indexed from, address indexed to, uint256 amount, uint256 redeemed);
uint256 constant CHI_NOT_SET = type(uint256).max;
uint256 constant internal MAX_TIME_TO_MATURITY = 126144000;
bytes32 constant internal FLASH_LOAN_RETURN = keccak256("ERC3156FlashBorrower.onFlashLoan");
uint256 constant FLASH_LOANS_DISABLED = type(uint256).max;
uint256 public flashFeeFactor = FLASH_LOANS_DISABLED;
IOracle public oracle;
IJoin public join;
address public immutable override underlying;
bytes6 public immutable underlyingId;
uint256 public immutable override maturity;
uint256 public chiAtMaturity = CHI_NOT_SET;
constructor(
bytes6 underlyingId_,
IOracle oracle_,
IJoin join_,
uint256 maturity_,
string memory name,
string memory symbol
) ERC20Permit(name, symbol, SafeERC20Namer.tokenDecimals(address(IJoin(join_).asset()))) {
uint256 now_ = block.timestamp;
require(
maturity_ > now_ &&
maturity_ < now_ + MAX_TIME_TO_MATURITY &&
maturity_ < type(uint32).max,
"Invalid maturity"
);
underlyingId = underlyingId_;
join = join_;
maturity = maturity_;
underlying = address(IJoin(join_).asset());
oracle = oracle_;
}
modifier afterMaturity() {
require(
uint32(block.timestamp) >= maturity,
"Only after maturity"
);
_;
}
modifier beforeMaturity() {
require(
uint32(block.timestamp) < maturity,
"Only before maturity"
);
_;
}
function point(bytes32 param, address value) external auth {
if (param == "oracle") oracle = IOracle(value);
else if (param == "join") join = IJoin(value);
else revert("Unrecognized parameter");
emit Point(param, value);
}
function setFlashFeeFactor(uint256 flashFeeFactor_)
external
auth
{
flashFeeFactor = flashFeeFactor_;
emit FlashFeeFactorSet(flashFeeFactor_);
}
function mature()
external override
afterMaturity
{
require (chiAtMaturity == CHI_NOT_SET, "Already matured");
_mature();
}
function _mature()
private
returns (uint256 _chiAtMaturity)
{
(_chiAtMaturity,) = oracle.get(underlyingId, CHI, 0);
chiAtMaturity = _chiAtMaturity;
emit SeriesMatured(_chiAtMaturity);
}
function accrual()
external
afterMaturity
returns (uint256)
{
return _accrual();
}
function _accrual()
private
returns (uint256 accrual_)
{
if (chiAtMaturity == CHI_NOT_SET) {
_mature();
} else {
(uint256 chi,) = oracle.get(underlyingId, CHI, 0);
accrual_ = chi.wdiv(chiAtMaturity);
}
accrual_ = accrual_ >= 1e18 ? accrual_ : 1e18;
}
function redeem(address to, uint256 amount)
external override
afterMaturity
returns (uint256 redeemed)
{
uint256 amount_ = (amount == 0) ? _balanceOf[address(this)] : amount;
_burn(msg.sender, amount_);
redeemed = amount_.wmul(_accrual());
join.exit(to, redeemed.u128());
emit Redeemed(msg.sender, to, amount_, redeemed);
}
function mintWithUnderlying(address to, uint256 amount)
external override
beforeMaturity
{
_mint(to, amount);
join.join(msg.sender, amount.u128());
}
function mint(address to, uint256 amount)
external override
beforeMaturity
auth
{
_mint(to, amount);
}
function burn(address from, uint256 amount)
external override
auth
{
_burn(from, amount);
}
function _burn(address from, uint256 amount)
internal override
returns (bool)
{
uint256 available = _balanceOf[address(this)];
if (available >= amount) {
return super._burn(address(this), amount);
} else {
if (available > 0 ) super._burn(address(this), available);
unchecked { _decreaseAllowance(from, amount - available); }
unchecked { return super._burn(from, amount - available); }
}
}
function maxFlashLoan(address token)
external view override
beforeMaturity
returns (uint256)
{
return token == address(this) ? type(uint256).max - _totalSupply : 0;
}
function flashFee(address token, uint256 amount)
external view override
returns (uint256)
{
require(token == address(this), "Unsupported currency");
return _flashFee(amount);
}
function _flashFee(uint256 amount) internal view returns (uint256) {
return amount.wmul(flashFeeFactor);
}
function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 amount, bytes memory data)
external override
beforeMaturity
returns(bool)
{
require(token == address(this), "Unsupported currency");
_mint(address(receiver), amount);
uint128 fee = _flashFee(amount).u128();
require(receiver.onFlashLoan(msg.sender, token, amount, fee, data) == FLASH_LOAN_RETURN, "Non-compliant borrower");
_burn(address(receiver), amount + fee);
return true;
}
}
文件 9 的 19: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 的 19: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 的 19: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 的 19:IERC3156FlashBorrower.sol
pragma solidity >=0.6.0 <0.9.0;
interface IERC3156FlashBorrower {
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}
文件 13 的 19:IERC3156FlashLender.sol
pragma solidity >=0.6.0 <0.9.0;
import "./IERC3156FlashBorrower.sol";
interface IERC3156FlashLender {
function maxFlashLoan(
address token
) external view returns (uint256);
function flashFee(
address token,
uint256 amount
) external view returns (uint256);
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}
文件 14 的 19:IFYToken.sol
pragma solidity ^0.8.0;
import "@yield-protocol/utils-v2/contracts/token/IERC20.sol";
interface IFYToken is IERC20 {
function underlying() external view returns (address);
function maturity() external view 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;
}
文件 15 的 19:IJoin.sol
pragma solidity ^0.8.0;
import "@yield-protocol/utils-v2/contracts/token/IERC20.sol";
interface IJoin {
function asset() external view returns (address);
function join(address user, uint128 wad) external returns (uint128);
function exit(address user, uint128 wad) external returns (uint128);
}
文件 16 的 19: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);
}
文件 17 的 19: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)) : 18;
}
}
文件 18 的 19:WDiv.sol
pragma solidity ^0.8.0;
library WDiv {
function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = (x * 1e18) / y;
}
}
文件 19 的 19:WMul.sol
pragma solidity ^0.8.0;
library WMul {
function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
unchecked { z /= 1e18; }
}
}
{
"compilationTarget": {
"@yield-protocol/vault-v2/contracts/FYToken.sol": "FYToken"
},
"evmVersion": "berlin",
"libraries": {
"@yield-protocol/utils-v2/contracts/token/SafeERC20Namer.sol:SafeERC20Namer": "0x39bb9cbe0221d769e30bd08d185842065bce1706"
},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"bytes6","name":"underlyingId_","type":"bytes6"},{"internalType":"contract IOracle","name":"oracle_","type":"address"},{"internalType":"contract IJoin","name":"join_","type":"address"},{"internalType":"uint256","name":"maturity_","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"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":true,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FlashFeeFactorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"param","type":"bytes32"},{"indexed":false,"internalType":"address","name":"value","type":"address"}],"name":"Point","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":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemed","type":"uint256"}],"name":"Redeemed","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":"chiAtMaturity","type":"uint256"}],"name":"SeriesMatured","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"},{"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":[],"name":"accrual","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chiAtMaturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashFeeFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":[],"name":"join","outputs":[{"internalType":"contract IJoin","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"lockRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintWithUnderlying","outputs":[],"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":[],"name":"oracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"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":[{"internalType":"bytes32","name":"param","type":"bytes32"},{"internalType":"address","name":"value","type":"address"}],"name":"point","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"redeemed","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":[{"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":"uint256","name":"flashFeeFactor_","type":"uint256"}],"name":"setFlashFeeFactor","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":"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":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingId","outputs":[{"internalType":"bytes6","name":"","type":"bytes6"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]