编译器
0.8.16+commit.07a7930e
文件 1 的 23:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 23:Address.sol
pragma solidity ^0.8.1;
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);
}
}
}
}
文件 3 的 23:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 23:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 23:ElasticERC20.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/utils/math/Math.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import './PricableAsset.sol';
abstract contract ElasticERC20 is Context, PricableAsset, IERC20Metadata {
using Math for uint256;
uint8 public constant DEFAULT_DECIMALS = 18;
uint256 public constant DEFAULT_DECIMALS_FACTOR = uint256(10)**DEFAULT_DECIMALS;
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function _convertToNominalWithCaching(uint256 value, Math.Rounding rounding)
internal
virtual
returns (uint256 nominal)
{
if (value == type(uint256).max) return type(uint256).max;
_cacheAssetPriceByBlock();
return value.mulDiv(DEFAULT_DECIMALS_FACTOR, assetPriceCached(), rounding);
}
function _convertFromNominalWithCaching(uint256 nominal, Math.Rounding rounding)
internal
virtual
returns (uint256 value)
{
if (nominal == type(uint256).max) return type(uint256).max;
_cacheAssetPriceByBlock();
return nominal.mulDiv(assetPriceCached(), DEFAULT_DECIMALS_FACTOR, rounding);
}
function _convertToNominalCached(uint256 value, Math.Rounding rounding)
internal
view
virtual
returns (uint256 nominal)
{
if (value == type(uint256).max) return type(uint256).max;
return value.mulDiv(DEFAULT_DECIMALS_FACTOR, assetPriceCached(), rounding);
}
function _convertFromNominalCached(uint256 nominal, Math.Rounding rounding)
internal
view
virtual
returns (uint256 value)
{
if (nominal == type(uint256).max) return type(uint256).max;
return nominal.mulDiv(assetPriceCached(), DEFAULT_DECIMALS_FACTOR, rounding);
}
function totalSupplyNominal() public view returns (uint256) {
return _totalSupply;
}
function balanceOfNominal(address account) public view returns (uint256) {
return _balances[account];
}
function allowanceNominal(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _convertFromNominalCached(_totalSupply, Math.Rounding.Down);
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _convertFromNominalCached(_balances[account], Math.Rounding.Down);
}
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
return _convertFromNominalCached(_allowances[owner][spender], Math.Rounding.Down);
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
_transferElastic(
_msgSender(),
to,
_convertToNominalCached(amount, Math.Rounding.Up),
amount
);
return true;
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approveElastic(_msgSender(), spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
uint256 nominalAmount = _convertToNominalCached(amount, Math.Rounding.Up);
_spendAllowanceElastic(from, _msgSender(), amount);
_transferElastic(from, to, nominalAmount, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approveElastic(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue)
public
virtual
returns (bool)
{
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(
currentAllowance >= subtractedValue,
'ElasticERC20: decreased allowance below zero'
);
unchecked {
_approveElastic(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transferElastic(
address from,
address to,
uint256 nominal,
uint256 value
) internal virtual {
require(from != address(0), 'ElasticERC20: transfer from the zero address');
require(to != address(0), 'ElasticERC20: transfer to the zero address');
uint256 fromBalance = _balances[from];
require(fromBalance >= nominal, 'ElasticERC20: transfer amount exceeds balance');
unchecked {
_balances[from] = fromBalance - nominal;
}
_balances[to] += nominal;
emit Transfer(from, to, value);
}
function _mintElastic(
address account,
uint256 nominal,
uint256 value
) internal virtual {
require(account != address(0), 'ElasticERC20: mint to the zero address');
_totalSupply += nominal;
_balances[account] += nominal;
emit Transfer(address(0), account, value);
}
function _burnElastic(
address account,
uint256 nominal,
uint256 value
) internal virtual {
require(account != address(0), 'ElasticERC20: burn from the zero address');
uint256 accountBalance = balanceOfNominal(account);
require(accountBalance >= nominal, 'ElasticERC20: burn amount exceeds balance');
unchecked {
_balances[account] = accountBalance - nominal;
}
_totalSupply -= nominal;
emit Transfer(account, address(0), value);
}
function _approveElastic(
address owner,
address spender,
uint256 value
) internal virtual {
require(owner != address(0), 'ElasticERC20: approve from the zero address');
require(spender != address(0), 'ElasticERC20: approve to the zero address');
_allowances[owner][spender] = _convertToNominalCached(value, Math.Rounding.Up);
emit Approval(owner, spender, value);
}
function _spendAllowanceElastic(
address owner,
address spender,
uint256 value
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= value, 'ElasticERC20: insufficient allowance');
unchecked {
_approveElastic(owner, spender, currentAllowance - value);
}
}
}
function _increaseBalanceElastic(address account, uint256 nominal) internal {
_totalSupply += nominal;
_balances[account] += nominal;
}
function _decreaseBalanceElastic(address account, uint256 nominal) internal {
_totalSupply -= nominal;
_balances[account] -= nominal;
}
}
文件 6 的 23:ElasticERC20RigidExtension.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/utils/math/Math.sol';
import './ElasticERC20.sol';
abstract contract ElasticERC20RigidExtension is ElasticERC20 {
using Math for uint256;
mapping(address => uint256) private _balancesRigid;
mapping(address => mapping(address => uint256)) private _allowancesRigid;
uint256 private _totalSupplyRigid;
uint256 private _lockedNominal;
event ConvertedToElastic(address indexed owner, uint256 value, uint256 nominal);
event ConvertedToRigid(address indexed owner, uint256 value, uint256 nominal);
function containRigidAddress(address _rigidAddress) public view virtual returns (bool);
function totalSupplyRigid() public view returns (uint256) {
return _totalSupplyRigid;
}
function lockedNominalRigid() public view returns (uint256) {
return _lockedNominal;
}
function totalSupply() public view virtual override returns (uint256) {
return super.totalSupply() + _totalSupplyRigid;
}
function balanceOf(address account) public view virtual override returns (uint256) {
if (!containRigidAddress(account)) return super.balanceOf(account);
return _balancesRigid[account];
}
function allowance(address owner, address spender)
public
view
virtual
override
returns (uint256)
{
if (!containRigidAddress(owner)) return super.allowance(owner, spender);
return _allowancesRigid[owner][spender];
}
function _convertRigidToElasticBalancePartially(address owner, uint256 amount) internal {
_totalSupplyRigid -= amount;
_balancesRigid[owner] -= amount;
uint256 nominal = _convertToNominalWithCaching(amount, Math.Rounding.Up);
_lockedNominal -= nominal;
_increaseBalanceElastic(owner, nominal);
emit ConvertedToElastic(owner, amount, nominal);
}
function _convertElasticToRigidBalancePartially(address owner, uint256 amount) internal {
uint256 nominal = _convertToNominalWithCaching(amount, Math.Rounding.Up);
_decreaseBalanceElastic(owner, nominal);
_lockedNominal += nominal;
_totalSupplyRigid += amount;
_balancesRigid[owner] += amount;
emit ConvertedToRigid(owner, amount, nominal);
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
if (containRigidAddress(owner)) {
_transferRigid(owner, to, amount);
if (!containRigidAddress(to)) _convertRigidToElasticBalancePartially(to, amount);
} else {
super.transfer(to, amount);
if (containRigidAddress(to)) _convertElasticToRigidBalancePartially(to, amount);
}
return true;
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
if (!containRigidAddress(owner)) return super.approve(spender, amount);
_approveRigid(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
if (containRigidAddress(from)) {
_spendAllowanceRigid(from, spender, amount);
_transferRigid(from, to, amount);
if (!containRigidAddress(to)) _convertRigidToElasticBalancePartially(to, amount);
} else {
super.transferFrom(from, to, amount);
if (containRigidAddress(to)) _convertElasticToRigidBalancePartially(to, amount);
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue)
public
virtual
override
returns (bool)
{
address owner = _msgSender();
if (!containRigidAddress(owner)) return super.increaseAllowance(spender, addedValue);
_approveRigid(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue)
public
virtual
override
returns (bool)
{
address owner = _msgSender();
if (!containRigidAddress(owner)) return super.decreaseAllowance(spender, subtractedValue);
uint256 currentAllowance = allowance(owner, spender);
require(
currentAllowance >= subtractedValue,
'RigidElasticERC20: decreased allowance below zero'
);
unchecked {
_approveRigid(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transferRigid(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), 'RigidElasticERC20: transfer from the zero address');
require(to != address(0), 'RigidElasticERC20: transfer to the zero address');
uint256 fromBalance = _balancesRigid[from];
require(fromBalance >= amount, 'RigidElasticERC20: transfer amount exceeds balance');
unchecked {
_balancesRigid[from] = fromBalance - amount;
}
_balancesRigid[to] += amount;
emit Transfer(from, to, amount);
}
function _approveRigid(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), 'RigidElasticERC20: approve from the zero address');
require(spender != address(0), 'RigidElasticERC20: approve to the zero address');
_allowancesRigid[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowanceRigid(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, 'RigidElasticERC20: insufficient allowance');
unchecked {
_approveRigid(owner, spender, currentAllowance - amount);
}
}
}
function _mintElastic(
address account,
uint256 nominal,
uint256 value
) internal virtual override {
if (!containRigidAddress(account)) return super._mintElastic(account, nominal, value);
revert("RigidElasticERC20: can't be minted");
}
function _burnElastic(
address account,
uint256 nominal,
uint256 value
) internal virtual override {
if (!containRigidAddress(account)) return super._burnElastic(account, nominal, value);
revert("RigidElasticERC20: can't be burned");
}
function _decreaseLockedNominalRigidBy(uint256 nominal) internal {
_lockedNominal -= nominal;
}
}
文件 7 的 23:ElasticRigidVault.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/utils/math/Math.sol';
import './interfaces/IElasticVault.sol';
import './ElasticERC20RigidExtension.sol';
abstract contract ElasticRigidVault is ElasticERC20RigidExtension, IElasticVault {
using Math for uint256;
IERC20Metadata private immutable _asset;
constructor(IERC20Metadata asset_) {
_asset = asset_;
}
function asset() public view virtual override returns (address) {
return address(_asset);
}
function totalAssets() public view virtual override returns (uint256) {
return _asset.balanceOf(address(this));
}
function convertToNominal(uint256 value)
public
view
virtual
override
returns (uint256 nominal)
{
return _convertToNominalCached(value, Math.Rounding.Down);
}
function convertToValue(uint256 nominal) public view virtual override returns (uint256 value) {
return _convertFromNominalCached(nominal, Math.Rounding.Down);
}
function maxDeposit(address) public view virtual override returns (uint256) {
return _isVaultCollateralized() ? type(uint256).max : 0;
}
function maxWithdraw(address owner) public view virtual override returns (uint256) {
return balanceOf(owner);
}
function previewDeposit(uint256 nominal) public view virtual override returns (uint256) {
return _convertFromNominalCached(nominal, Math.Rounding.Down);
}
function _previewDepositWithCaching(uint256 nominal) internal virtual returns (uint256) {
return _convertFromNominalWithCaching(nominal, Math.Rounding.Down);
}
function previewWithdraw(uint256 value) public view virtual override returns (uint256) {
uint256 nominal = _convertToNominalCached(value, Math.Rounding.Down);
uint256 nominalFee = _calcFee(
_msgSender(),
nominal
);
return nominal - nominalFee;
}
function _previewWithdrawWithCaching(uint256 value) internal virtual returns (uint256) {
return _convertToNominalWithCaching(value, Math.Rounding.Down);
}
function deposit(uint256 nominal, address receiver) public virtual override returns (uint256) {
require(nominal <= maxDeposit(receiver), 'ElasticVault: deposit more than max');
uint256 value = _previewDepositWithCaching(nominal);
_deposit(_msgSender(), receiver, value, nominal);
return value;
}
function withdraw(
uint256 value,
address receiver,
address owner
) public virtual override returns (uint256) {
uint256 nominal = _previewWithdrawWithCaching(value);
require(nominal <= balanceOfNominal(owner), 'ElasticVault: withdraw more than max');
_withdraw(_msgSender(), receiver, owner, value, nominal);
return nominal;
}
function withdrawAll(address receiver, address owner) public virtual returns (uint256) {
uint256 nominal = balanceOfNominal(owner);
uint256 value = balanceOf(owner);
_withdraw(_msgSender(), receiver, owner, value, nominal);
return nominal;
}
function _beforeDeposit(
address caller,
address receiver,
uint256 value,
uint256 nominal
) internal virtual {}
function _deposit(
address caller,
address receiver,
uint256 value,
uint256 nominal
) internal virtual {
_beforeDeposit(caller, receiver, value, nominal);
SafeERC20.safeTransferFrom(IERC20Metadata(asset()), caller, address(this), nominal);
_mintElastic(receiver, nominal, value);
emit Deposit(caller, receiver, value, nominal);
}
function _beforeWithdraw(
address caller,
address receiver,
address owner,
uint256 value,
uint256 nominal
) internal virtual {}
function _calcFee(address, uint256) internal view virtual returns (uint256 nominalFee) {
return 0;
}
function _withdrawFee(uint256 nominal) internal virtual {}
function _withdraw(
address caller,
address receiver,
address owner,
uint256 value,
uint256 nominal
) internal virtual {
_beforeWithdraw(caller, receiver, owner, value, nominal);
if (caller != owner) {
_spendAllowanceElastic(owner, caller, value);
}
uint256 nominalFee = _calcFee(caller, nominal);
_withdrawFee(nominalFee);
_burnElastic(owner, nominal, value);
SafeERC20.safeTransfer(IERC20Metadata(asset()), receiver, nominal - nominalFee);
emit Withdraw(caller, receiver, owner, value, nominal, nominalFee);
}
function _isVaultCollateralized() private view returns (bool) {
return totalAssets() > 0 || totalSupplyNominal() == 0;
}
}
文件 8 的 23:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[toDeleteIndex] = lastValue;
set._indexes[lastValue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 9 的 23:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 10 的 23:IAssetPriceOracle.sol
pragma solidity ^0.8.0;
interface IAssetPriceOracle {
function lpPrice() external view returns (uint256);
}
文件 11 的 23:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 12 的 23:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 13 的 23: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);
}
文件 14 的 23:IElasticVault.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
interface IElasticVault is IERC20, IERC20Metadata {
event Deposit(address indexed caller, address indexed owner, uint256 value, uint256 nominal);
event Withdraw(
address indexed caller,
address indexed receiver,
address indexed owner,
uint256 value,
uint256 nominal,
uint256 fee
);
function asset() external view returns (address assetTokenAddress);
function totalAssets() external view returns (uint256 totalManagedAssets);
function convertToNominal(uint256 value) external view returns (uint256 nominal);
function convertToValue(uint256 nominal) external view returns (uint256 value);
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
function previewDeposit(uint256 assets) external view returns (uint256 shares);
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
function withdraw(
uint256 assets,
address receiver,
address owner
) external returns (uint256 shares);
}
文件 15 的 23:IRedistributor.sol
pragma solidity ^0.8.0;
interface IRedistributor {
function requestRedistribution(uint256 nominal) external;
}
文件 16 的 23:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1;
uint256 x = a;
if (x >> 128 > 0) {
x >>= 128;
result <<= 64;
}
if (x >> 64 > 0) {
x >>= 64;
result <<= 32;
}
if (x >> 32 > 0) {
x >>= 32;
result <<= 16;
}
if (x >> 16 > 0) {
x >>= 16;
result <<= 8;
}
if (x >> 8 > 0) {
x >>= 8;
result <<= 4;
}
if (x >> 4 > 0) {
x >>= 4;
result <<= 2;
}
if (x >> 2 > 0) {
result <<= 1;
}
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
uint256 result = sqrt(a);
if (rounding == Rounding.Up && result * result < a) {
result += 1;
}
return result;
}
}
文件 17 的 23:PricableAsset.sol
pragma solidity ^0.8.0;
import './interfaces/IAssetPriceOracle.sol';
abstract contract PricableAsset {
uint256 private _blockCached;
uint256 private _assetPriceCached;
event CachedAssetPrice(uint256 blockNumber, uint256 assetPrice);
function assetPriceCacheDuration() public view virtual returns (uint256);
function assetPrice() public view virtual returns (uint256);
function assetPriceCached() public view virtual returns (uint256) {
return _assetPriceCached;
}
function blockCached() public view virtual returns (uint256) {
return _blockCached;
}
function cacheAssetPrice() public virtual {
_blockCached = block.number;
uint256 currentAssetPrice = assetPrice();
if (_assetPriceCached < currentAssetPrice) {
_assetPriceCached = currentAssetPrice;
emit CachedAssetPrice(_blockCached, _assetPriceCached);
}
}
function _cacheAssetPriceByBlock() internal virtual {
if (block.number >= _blockCached + assetPriceCacheDuration()) {
cacheAssetPrice();
}
}
function _resetPriceCache() internal virtual {
_blockCached = 0;
_assetPriceCached = 0;
}
}
文件 18 的 23:RigidAddressSet.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
contract RigidAddressSet {
using EnumerableSet for EnumerableSet.AddressSet;
EnumerableSet.AddressSet private _rigidAddresses;
event AddedRigidAddress(address indexed rigidAddress);
event RemovedRigidAddress(address indexed rigidAddress);
function rigidAddresses() public view returns (address[] memory) {
return _rigidAddresses.values();
}
function _addRigidAddress(address _rigidAddress) internal {
if(_rigidAddresses.add(_rigidAddress)) {
emit AddedRigidAddress(_rigidAddress);
} else {
revert("RigidAddressSet: add existed address");
}
}
function _removeRigidAddress(address _rigidAddress) internal {
if(_rigidAddresses.remove(_rigidAddress)){
emit RemovedRigidAddress(_rigidAddress);
} else {
revert("RigidAddressSet: remove un-existed address");
}
}
function _containRigidAddress(address _rigidAddress) internal view returns (bool) {
return _rigidAddresses.contains(_rigidAddress);
}
}
文件 19 的 23:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/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 safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
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");
}
}
}
文件 20 的 23:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 21 的 23:UZD.sol
pragma solidity ^0.8.0;
import './ZunamiElasticRigidVault.sol';
contract UZD is ZunamiElasticRigidVault {
address public constant ZUNAMI = 0x2ffCC661011beC72e1A9524E12060983E74D14ce;
constructor()
ElasticERC20('UZD Zunami Stable', 'UZD')
ElasticRigidVault(IERC20Metadata(ZUNAMI))
ZunamiElasticRigidVault(ZUNAMI)
{}
}
文件 22 的 23:ZunamiElasticRigidVault.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/AccessControl.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import './ElasticRigidVault.sol';
import './RigidAddressSet.sol';
import './interfaces/IRedistributor.sol';
abstract contract ZunamiElasticRigidVault is AccessControl, ElasticRigidVault, RigidAddressSet {
using Math for uint256;
bytes32 public constant REBALANCER_ROLE = keccak256('REBALANCER_ROLE');
uint256 public constant FEE_DENOMINATOR = 1000000;
uint256 public constant MAX_FEE = 50000;
uint256 public withdrawFee;
address public feeDistributor;
uint256 public dailyDepositDuration;
uint256 public dailyDepositLimit;
uint256 public dailyWithdrawDuration;
uint256 public dailyWithdrawLimit;
uint256 public dailyDepositTotal;
uint256 public dailyDepositCountingBlock;
uint256 public dailyWithdrawTotal;
uint256 public dailyWithdrawCountingBlock;
IAssetPriceOracle public immutable priceOracle;
IRedistributor public redistributor;
uint256 private _assetPriceCacheDuration = 1200;
event AssetPriceCacheDurationSet(
uint256 newAssetPriceCacheDuration,
uint256 oldAssetPriceCacheDuration
);
event DailyDepositParamsChanged(uint256 dailyDepositDuration, uint256 dailyDepositLimit);
event DailyWithdrawParamsChanged(uint256 dailyWithdrawDuration, uint256 dailyWithdrawLimit);
event WithdrawFeeChanged(uint256 withdrawFee);
event FeeDistributorChanged(address feeDistributor);
event RedistributorChanged(address redistributor);
constructor(address priceOracle_) {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
require(priceOracle_ != address(0), 'Zero price oracle');
priceOracle = IAssetPriceOracle(priceOracle_);
cacheAssetPrice();
}
function assetPrice() public view override returns (uint256) {
return priceOracle.lpPrice();
}
function assetPriceCacheDuration() public view override returns (uint256) {
return _assetPriceCacheDuration;
}
function setAssetPriceCacheDuration(uint256 assetPriceCacheDuration_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
emit AssetPriceCacheDurationSet(assetPriceCacheDuration_, _assetPriceCacheDuration);
_assetPriceCacheDuration = assetPriceCacheDuration_;
}
function changeDailyDepositParams(uint256 dailyDepositDuration_, uint256 dailyDepositLimit_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
dailyDepositDuration = dailyDepositDuration_;
dailyDepositLimit = dailyDepositLimit_;
dailyDepositTotal = 0;
dailyDepositCountingBlock = dailyDepositDuration_ > 0 ? block.number : 0;
emit DailyDepositParamsChanged(dailyDepositDuration_, dailyDepositLimit_);
}
function changeDailyWithdrawParams(uint256 dailyWithdrawDuration_, uint256 dailyWithdrawLimit_)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
dailyWithdrawDuration = dailyWithdrawDuration_;
dailyWithdrawLimit = dailyWithdrawLimit_;
dailyWithdrawTotal = 0;
dailyWithdrawCountingBlock = dailyWithdrawDuration_ > 0 ? block.number : 0;
emit DailyWithdrawParamsChanged(dailyWithdrawDuration_, dailyWithdrawLimit_);
}
function changeWithdrawFee(uint256 withdrawFee_) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(withdrawFee_ <= MAX_FEE, 'Bigger that MAX_FEE constant');
withdrawFee = withdrawFee_;
emit WithdrawFeeChanged(withdrawFee_);
}
function changeFeeDistributor(address feeDistributor_) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(feeDistributor_ != address(0), 'Zero fee distributor');
feeDistributor = feeDistributor_;
emit FeeDistributorChanged(feeDistributor_);
}
function _beforeDeposit(
address caller,
address,
uint256 value,
uint256
) internal override {
uint256 dailyDuration = dailyDepositDuration;
if (dailyDuration > 0 && !hasRole(REBALANCER_ROLE, caller)) {
if (block.number > dailyDepositCountingBlock + dailyDuration) {
dailyDepositTotal = value;
dailyDepositCountingBlock = block.number;
} else {
dailyDepositTotal += value;
}
require(dailyDepositTotal <= dailyDepositLimit, 'Daily deposit limit overflow');
}
}
function _beforeWithdraw(
address caller,
address,
address,
uint256 value,
uint256
) internal override {
uint256 dailyDuration = dailyWithdrawDuration;
if (dailyDuration > 0 && !hasRole(REBALANCER_ROLE, caller)) {
if (block.number > dailyWithdrawCountingBlock + dailyDuration) {
dailyWithdrawTotal = value;
dailyWithdrawCountingBlock = block.number;
} else {
dailyWithdrawTotal += value;
}
require(dailyWithdrawTotal <= dailyWithdrawLimit, 'Daily withdraw limit overflow');
}
}
function _calcFee(address caller, uint256 nominal)
internal
view
override
returns (uint256 nominalFee)
{
nominalFee = 0;
uint256 withdrawFee_ = withdrawFee;
if (withdrawFee_ > 0 && !hasRole(REBALANCER_ROLE, caller)) {
nominalFee = nominal.mulDiv(withdrawFee_, FEE_DENOMINATOR, Math.Rounding.Down);
}
}
function _withdrawFee(uint256 nominalFee) internal override {
if (nominalFee > 0) {
SafeERC20.safeTransfer(IERC20Metadata(asset()), feeDistributor, nominalFee);
}
}
function containRigidAddress(address _rigidAddress) public view override returns (bool) {
return _containRigidAddress(_rigidAddress);
}
function addRigidAddress(address _rigidAddress) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(!containRigidAddress(_rigidAddress), 'Not elastic address');
uint256 balanceElastic = balanceOf(_rigidAddress);
_addRigidAddress(_rigidAddress);
if (balanceElastic > 0) {
_convertElasticToRigidBalancePartially(_rigidAddress, balanceElastic);
}
}
function removeRigidAddress(address _rigidAddress) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(containRigidAddress(_rigidAddress), 'Not rigid address');
uint256 balanceRigid = balanceOf(_rigidAddress);
_removeRigidAddress(_rigidAddress);
if (balanceRigid > 0) {
_convertRigidToElasticBalancePartially(_rigidAddress, balanceRigid);
}
}
function setRedistributor(address _redistributor) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(_redistributor != address(0), 'Zero redistributor address');
redistributor = IRedistributor(_redistributor);
emit RedistributorChanged(_redistributor);
}
function redistribute() public {
uint256 totalRigidNominal = _convertToNominalWithCaching(
totalSupplyRigid(),
Math.Rounding.Up
);
uint256 lockedNominalRigid_ = lockedNominalRigid();
require(
lockedNominalRigid_ >= totalRigidNominal,
'Wrong redistribution total nominal balance'
);
uint256 nominal;
unchecked {
nominal = lockedNominalRigid_ - totalRigidNominal;
}
_decreaseLockedNominalRigidBy(nominal);
IRedistributor redistributor_ = redistributor;
SafeERC20.safeIncreaseAllowance(IERC20Metadata(asset()), address(redistributor_), nominal);
redistributor_.requestRedistribution(nominal);
}
}
文件 23 的 23:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"contracts/UZD.sol": "UZD"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rigidAddress","type":"address"}],"name":"AddedRigidAddress","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":false,"internalType":"uint256","name":"newAssetPriceCacheDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldAssetPriceCacheDuration","type":"uint256"}],"name":"AssetPriceCacheDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetPrice","type":"uint256"}],"name":"CachedAssetPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nominal","type":"uint256"}],"name":"ConvertedToElastic","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nominal","type":"uint256"}],"name":"ConvertedToRigid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dailyDepositDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dailyDepositLimit","type":"uint256"}],"name":"DailyDepositParamsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dailyWithdrawDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dailyWithdrawLimit","type":"uint256"}],"name":"DailyWithdrawParamsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nominal","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeDistributor","type":"address"}],"name":"FeeDistributorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"redistributor","type":"address"}],"name":"RedistributorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rigidAddress","type":"address"}],"name":"RemovedRigidAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nominal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawFee","type":"uint256"}],"name":"WithdrawFeeChanged","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_DECIMALS_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REBALANCER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZUNAMI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rigidAddress","type":"address"}],"name":"addRigidAddress","outputs":[],"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":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowanceNominal","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":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetPriceCacheDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetPriceCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfNominal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cacheAssetPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dailyDepositDuration_","type":"uint256"},{"internalType":"uint256","name":"dailyDepositLimit_","type":"uint256"}],"name":"changeDailyDepositParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dailyWithdrawDuration_","type":"uint256"},{"internalType":"uint256","name":"dailyWithdrawLimit_","type":"uint256"}],"name":"changeDailyWithdrawParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feeDistributor_","type":"address"}],"name":"changeFeeDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawFee_","type":"uint256"}],"name":"changeWithdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rigidAddress","type":"address"}],"name":"containRigidAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"convertToNominal","outputs":[{"internalType":"uint256","name":"nominal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nominal","type":"uint256"}],"name":"convertToValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyDepositCountingBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyDepositDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyDepositLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyDepositTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyWithdrawCountingBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyWithdrawDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyWithdrawLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyWithdrawTotal","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":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nominal","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedNominalRigid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","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":"uint256","name":"nominal","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceOracle","outputs":[{"internalType":"contract IAssetPriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redistribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redistributor","outputs":[{"internalType":"contract IRedistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rigidAddress","type":"address"}],"name":"removeRigidAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rigidAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetPriceCacheDuration_","type":"uint256"}],"name":"setAssetPriceCacheDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_redistributor","type":"address"}],"name":"setRedistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyNominal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyRigid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdrawAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]