文件 1 的 12:ERC20.sol
pragma solidity 0.8.7;
import { IERC20 } from "./interfaces/IERC20.sol";
contract ERC20 is IERC20 {
string public override name;
string public override symbol;
uint8 public immutable override decimals;
uint256 public override totalSupply;
mapping(address => uint256) public override balanceOf;
mapping(address => mapping(address => uint256)) public override allowance;
bytes32 private constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
uint256 internal immutable initialChainId;
bytes32 internal immutable initialDomainSeparator;
mapping(address => uint256) public override nonces;
constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
decimals = decimals_;
initialChainId = block.chainid;
initialDomainSeparator = _computeDomainSeparator();
}
function approve(address spender_, uint256 amount_) external override returns (bool success_) {
_approve(msg.sender, spender_, amount_);
return true;
}
function decreaseAllowance(address spender_, uint256 subtractedAmount_) external override returns (bool success_) {
_decreaseAllowance(msg.sender, spender_, subtractedAmount_);
return true;
}
function increaseAllowance(address spender_, uint256 addedAmount_) external override returns (bool success_) {
_approve(msg.sender, spender_, allowance[msg.sender][spender_] + addedAmount_);
return true;
}
function permit(address owner_, address spender_, uint256 amount_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_) external override {
require(deadline_ >= block.timestamp, "ERC20:P:EXPIRED");
require(
uint256(s_) <= uint256(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) &&
(v_ == 27 || v_ == 28),
"ERC20:P:MALLEABLE"
);
unchecked {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(abi.encode(PERMIT_TYPEHASH, owner_, spender_, amount_, nonces[owner_]++, deadline_))
)
);
address recoveredAddress = ecrecover(digest, v_, r_, s_);
require(recoveredAddress == owner_ && owner_ != address(0), "ERC20:P:INVALID_SIGNATURE");
}
_approve(owner_, spender_, amount_);
}
function transfer(address recipient_, uint256 amount_) external override returns (bool success_) {
_transfer(msg.sender, recipient_, amount_);
return true;
}
function transferFrom(address owner_, address recipient_, uint256 amount_) external override returns (bool success_) {
_decreaseAllowance(owner_, msg.sender, amount_);
_transfer(owner_, recipient_, amount_);
return true;
}
function DOMAIN_SEPARATOR() public view virtual override returns (bytes32 domainSeparator_) {
return block.chainid == initialChainId ? initialDomainSeparator : _computeDomainSeparator();
}
function _approve(address owner_, address spender_, uint256 amount_) internal {
emit Approval(owner_, spender_, allowance[owner_][spender_] = amount_);
}
function _burn(address owner_, uint256 amount_) internal virtual {
balanceOf[owner_] -= amount_;
unchecked { totalSupply -= amount_; }
emit Transfer(owner_, address(0), amount_);
}
function _computeDomainSeparator() internal view virtual returns (bytes32 domainSeparator_) {
return keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
block.chainid,
address(this)
)
);
}
function _decreaseAllowance(address owner_, address spender_, uint256 subtractedAmount_) internal {
uint256 spenderAllowance = allowance[owner_][spender_];
if (spenderAllowance != type(uint256).max) {
_approve(owner_, spender_, spenderAllowance - subtractedAmount_);
}
}
function _mint(address recipient_, uint256 amount_) internal virtual {
totalSupply += amount_;
unchecked { balanceOf[recipient_] += amount_; }
emit Transfer(address(0), recipient_, amount_);
}
function _transfer(address owner_, address recipient_, uint256 amount_) internal virtual {
balanceOf[owner_] -= amount_;
unchecked { balanceOf[recipient_] += amount_; }
emit Transfer(owner_, recipient_, amount_);
}
}
文件 2 的 12:ERC20Helper.sol
pragma solidity ^0.8.7;
import { IERC20Like } from "./interfaces/IERC20Like.sol";
library ERC20Helper {
function transfer(address token_, address to_, uint256 amount_) internal returns (bool success_) {
return _call(token_, abi.encodeWithSelector(IERC20Like.transfer.selector, to_, amount_));
}
function transferFrom(address token_, address from_, address to_, uint256 amount_) internal returns (bool success_) {
return _call(token_, abi.encodeWithSelector(IERC20Like.transferFrom.selector, from_, to_, amount_));
}
function approve(address token_, address spender_, uint256 amount_) internal returns (bool success_) {
if (!_call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, uint256(0)))) return false;
if (amount_ == uint256(0)) return true;
return _call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, amount_));
}
function _call(address token_, bytes memory data_) private returns (bool success_) {
if (token_.code.length == uint256(0)) return false;
bytes memory returnData;
( success_, returnData ) = token_.call(data_);
return success_ && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
}
}
文件 3 的 12:GovernanceLockedRevenueDistributionToken.sol
pragma solidity ^0.8.7;
import {ERC20} from "erc20/ERC20.sol";
import {RevenueDistributionToken} from "revenue-distribution-token/RevenueDistributionToken.sol";
import {LockedRevenueDistributionToken} from "./LockedRevenueDistributionToken.sol";
import {IGovernanceLockedRevenueDistributionToken} from "./interfaces/IGovernanceLockedRevenueDistributionToken.sol";
import {Math} from "./libraries/Math.sol";
contract GovernanceLockedRevenueDistributionToken is
IGovernanceLockedRevenueDistributionToken,
LockedRevenueDistributionToken
{
bytes32 private constant DELEGATE_TYPEHASH = 0xe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf;
mapping(address => address) public delegates;
mapping(address => Checkpoint[]) public override userCheckpoints;
Checkpoint[] private totalSupplyCheckpoints;
constructor(
string memory name_,
string memory symbol_,
address owner_,
address asset_,
uint256 precision_,
uint256 instantWithdrawalFee_,
uint256 lockTime_,
uint256 initialSeed_
)
LockedRevenueDistributionToken(
name_,
symbol_,
owner_,
asset_,
precision_,
instantWithdrawalFee_,
lockTime_,
initialSeed_
)
{}
function delegate(address delegatee_) external virtual override {
_delegate(msg.sender, delegatee_);
}
function delegateBySig(address delegatee_, uint256 nonce_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_)
public
virtual
override
{
require(deadline_ >= block.timestamp, "GLRDT:DBS:EXPIRED");
require(
uint256(s_) <= uint256(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0)
&& (v_ == 27 || v_ == 28),
"GLRDT:DBS:MALLEABLE"
);
bytes32 digest_ = keccak256(
abi.encodePacked(
"\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(DELEGATE_TYPEHASH, delegatee_, nonce_, deadline_))
)
);
address recoveredAddress_ = ecrecover(digest_, v_, r_, s_);
require(recoveredAddress_ != address(0), "GLRDT:DBS:INVALID_SIGNATURE");
unchecked {
require(nonce_ == nonces[recoveredAddress_]++, "GLRDT:DBS:INVALID_NONCE");
}
_delegate(recoveredAddress_, delegatee_);
}
function convertToAssets(uint256 shares_, uint256 blockNumber_)
public
view
virtual
override
returns (uint256 assets_)
{
(uint256 totalSupply_, uint256 totalAssets_) = _checkpointsLookup(totalSupplyCheckpoints, blockNumber_);
assets_ = totalSupply_ == 0 ? shares_ : (shares_ * totalAssets_) / totalSupply_;
}
function checkpoints(address account_, uint32 pos_)
external
view
virtual
override
returns (uint32 fromBlock_, uint96 votes_)
{
Checkpoint memory checkpoint_ = userCheckpoints[account_][pos_];
fromBlock_ = checkpoint_.fromBlock;
votes_ = checkpoint_.assets;
}
function numCheckpoints(address account_) public view virtual override returns (uint32 numCheckpoints_) {
numCheckpoints_ = _toUint32(userCheckpoints[account_].length);
}
function getVotes(address account_) public view virtual override returns (uint256 votes_) {
uint256 pos_ = userCheckpoints[account_].length;
if (pos_ == 0) {
return 0;
}
uint256 shares_ = userCheckpoints[account_][pos_ - 1].shares;
votes_ = convertToAssets(shares_, block.number);
}
function getCurrentVotes(address account_) external view virtual override returns (uint96 votes_) {
votes_ = _toUint96(getVotes(account_));
}
function getPastVotes(address account_, uint256 blockNumber_)
public
view
virtual
override
returns (uint256 votes_)
{
require(blockNumber_ < block.number, "GLRDT:BLOCK_NOT_MINED");
(uint256 shares_,) = _checkpointsLookup(userCheckpoints[account_], blockNumber_);
votes_ = convertToAssets(shares_, blockNumber_);
}
function getPriorVotes(address account_, uint256 blockNumber_)
external
view
virtual
override
returns (uint96 votes_)
{
votes_ = _toUint96(getPastVotes(account_, blockNumber_));
}
function getPastTotalSupply(uint256 blockNumber_) external view virtual override returns (uint256 totalSupply_) {
require(blockNumber_ < block.number, "GLRDT:BLOCK_NOT_MINED");
(totalSupply_,) = _checkpointsLookup(totalSupplyCheckpoints, blockNumber_);
}
function _mint(uint256 shares_, uint256 assets_, address receiver_, address caller_) internal virtual override {
super._mint(shares_, assets_, receiver_, caller_);
_moveVotingPower(address(0), delegates[receiver_], shares_);
_writeCheckpoint(totalSupplyCheckpoints, _add, shares_);
}
function _burn(uint256 shares_, uint256 assets_, address receiver_, address owner_, address caller_)
internal
virtual
override
{
super._burn(shares_, assets_, receiver_, owner_, caller_);
_moveVotingPower(delegates[owner_], address(0), shares_);
_writeCheckpoint(totalSupplyCheckpoints, _subtract, shares_);
}
function _transfer(address owner_, address recipient_, uint256 amount_) internal virtual override {
super._transfer(owner_, recipient_, amount_);
_moveVotingPower(delegates[owner_], delegates[recipient_], amount_);
}
function _delegate(address delegator_, address delegatee_) internal virtual {
address currentDelegate_ = delegates[delegator_];
uint256 delegatorBalance_ = balanceOf[delegator_];
delegates[delegator_] = delegatee_;
emit DelegateChanged(delegator_, currentDelegate_, delegatee_);
_moveVotingPower(currentDelegate_, delegatee_, delegatorBalance_);
}
function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber_)
private
view
returns (uint96 shares_, uint96 assets_)
{
uint256 length_ = ckpts.length;
uint256 low_ = 0;
uint256 high_ = length_;
if (length_ > 5) {
uint256 mid_ = length_ - Math.sqrt(length_);
if (_unsafeAccess(ckpts, mid_).fromBlock > blockNumber_) {
high_ = mid_;
} else {
low_ = mid_ + 1;
}
}
while (low_ < high_) {
uint256 mid_ = Math.average(low_, high_);
if (_unsafeAccess(ckpts, mid_).fromBlock > blockNumber_) {
high_ = mid_;
} else {
low_ = mid_ + 1;
}
}
if (high_ == 0) {
return (0, 0);
}
Checkpoint memory checkpoint_ = _unsafeAccess(ckpts, high_ - 1);
return (checkpoint_.shares, checkpoint_.assets);
}
function _moveVotingPower(address src_, address dst_, uint256 amount_) private {
if (src_ != dst_ && amount_ > 0) {
if (src_ != address(0)) {
(uint256 oldWeight_, uint256 newWeight_) = _writeCheckpoint(userCheckpoints[src_], _subtract, amount_);
emit DelegateVotesChanged(src_, oldWeight_, newWeight_);
}
if (dst_ != address(0)) {
(uint256 oldWeight_, uint256 newWeight_) = _writeCheckpoint(userCheckpoints[dst_], _add, amount_);
emit DelegateVotesChanged(dst_, oldWeight_, newWeight_);
}
}
}
function _writeCheckpoint(
Checkpoint[] storage ckpts,
function(uint256, uint256) view returns (uint256) op_,
uint256 delta_
) private returns (uint256 oldWeight_, uint256 newWeight_) {
uint256 pos_ = ckpts.length;
Checkpoint memory oldCkpt_ = pos_ == 0 ? Checkpoint(0, 0, 0) : _unsafeAccess(ckpts, pos_ - 1);
oldWeight_ = oldCkpt_.shares;
newWeight_ = op_(oldWeight_, delta_);
if (pos_ > 0 && oldCkpt_.fromBlock == block.number) {
_unsafeAccess(ckpts, pos_ - 1).shares = _toUint96(newWeight_);
_unsafeAccess(ckpts, pos_ - 1).assets = _toUint96(convertToAssets(newWeight_));
} else {
ckpts.push(
Checkpoint({
fromBlock: _toUint32(block.number),
shares: _toUint96(newWeight_),
assets: _toUint96(convertToAssets(newWeight_))
})
);
}
}
function _add(uint256 a_, uint256 b_) private pure returns (uint256 result_) {
return a_ + b_;
}
function _subtract(uint256 a_, uint256 b_) private pure returns (uint256 result_) {
return a_ - b_;
}
function _toUint32(uint256 value_) private pure returns (uint32) {
require(value_ <= type(uint32).max, "GLRDT:CAST_EXCEEDS_32_BITS");
return uint32(value_);
}
function _toUint96(uint256 value_) private pure returns (uint96) {
require(value_ <= type(uint96).max, "GLRDT:CAST_EXCEEDS_96_BITS");
return uint96(value_);
}
function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos_) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, ckpts.slot)
result.slot := add(keccak256(0, 0x20), pos_)
}
}
}
文件 4 的 12:IERC20.sol
pragma solidity 0.8.7;
interface IERC20 {
event Approval(address indexed owner_, address indexed spender_, uint256 amount_);
event Transfer(address indexed owner_, address indexed recipient_, uint256 amount_);
function approve(address spender_, uint256 amount_) external returns (bool success_);
function decreaseAllowance(address spender_, uint256 subtractedAmount_) external returns (bool success_);
function increaseAllowance(address spender_, uint256 addedAmount_) external returns (bool success_);
function permit(address owner_, address spender_, uint amount_, uint deadline_, uint8 v_, bytes32 r_, bytes32 s_) external;
function transfer(address recipient_, uint256 amount_) external returns (bool success_);
function transferFrom(address owner_, address recipient_, uint256 amount_) external returns (bool success_);
function allowance(address owner_, address spender_) external view returns (uint256 allowance_);
function balanceOf(address account_) external view returns (uint256 balance_);
function decimals() external view returns (uint8 decimals_);
function DOMAIN_SEPARATOR() external view returns (bytes32 domainSeparator_);
function name() external view returns (string memory name_);
function nonces(address owner_) external view returns (uint256 nonce_);
function symbol() external view returns (string memory symbol_);
function totalSupply() external view returns (uint256 totalSupply_);
}
文件 5 的 12:IERC20Like.sol
pragma solidity ^0.8.7;
interface IERC20Like {
function approve(address spender_, uint256 amount_) external returns (bool success_);
function transfer(address recipient_, uint256 amount_) external returns (bool success_);
function transferFrom(address owner_, address recipient_, uint256 amount_) external returns (bool success_);
}
文件 6 的 12:IERC4626.sol
pragma solidity 0.8.7;
import { IERC20 } from "erc20/interfaces/IERC20.sol";
interface IERC4626 is IERC20 {
event Deposit(address indexed caller_, address indexed owner_, uint256 assets_, uint256 shares_);
event Withdraw(address indexed caller_, address indexed receiver_, address indexed owner_, uint256 assets_, uint256 shares_);
function asset() external view returns (address asset_);
function deposit(uint256 assets_, address receiver_) external returns (uint256 shares_);
function mint(uint256 shares_, address receiver_) external returns (uint256 assets_);
function redeem(uint256 shares_, address receiver_, address owner_) external returns (uint256 assets_);
function withdraw(uint256 assets_, address receiver_, address owner_) external returns (uint256 shares_);
function convertToAssets(uint256 shares_) external view returns (uint256 assets_);
function convertToShares(uint256 assets_) external view returns (uint256 shares_);
function maxDeposit(address receiver_) external view returns (uint256 assets_);
function maxMint(address receiver_) external view returns (uint256 shares_);
function maxRedeem(address owner_) external view returns (uint256 shares_);
function maxWithdraw(address owner_) external view returns (uint256 assets_);
function previewDeposit(uint256 assets_) external view returns (uint256 shares_);
function previewMint(uint256 shares_) external view returns (uint256 assets_);
function previewRedeem(uint256 shares_) external view returns (uint256 assets_);
function previewWithdraw(uint256 assets_) external view returns (uint256 shares_);
function totalAssets() external view returns (uint256 totalAssets_);
}
文件 7 的 12:IGovernanceLockedRevenueDistributionToken.sol
pragma solidity ^0.8.7;
interface IGovernanceLockedRevenueDistributionToken {
struct Checkpoint {
uint32 fromBlock;
uint96 shares;
uint96 assets;
}
event DelegateChanged(address indexed delegator_, address indexed fromDelegate_, address indexed toDelegate_);
event DelegateVotesChanged(address indexed delegate_, uint256 previousBalance_, uint256 newBalance_);
function userCheckpoints(address account_, uint256 pos_)
external
view
returns (uint32 fromBlock, uint96 shares, uint96 assets);
function delegate(address delegatee_) external;
function delegateBySig(address delegatee_, uint256 nonce_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_)
external;
function convertToAssets(uint256 shares_, uint256 blockNumber_) external view returns (uint256 assets_);
function checkpoints(address account_, uint32 pos_) external view returns (uint32 fromBlock_, uint96 votes_);
function numCheckpoints(address account_) external view returns (uint32);
function getVotes(address account_) external view returns (uint256 votes_);
function getCurrentVotes(address account_) external view returns (uint96 votes_);
function getPastVotes(address account_, uint256 blockNumber_) external view returns (uint256 votes_);
function getPriorVotes(address account_, uint256 blockNumber_) external view returns (uint96 votes_);
function getPastTotalSupply(uint256 blockNumber_) external view returns (uint256 totalSupply_);
}
文件 8 的 12:ILockedRevenueDistributionToken.sol
pragma solidity ^0.8.7;
interface ILockedRevenueDistributionToken {
struct WithdrawalRequest {
uint32 unlockedAt;
uint32 lockTime;
uint96 shares;
uint96 assets;
}
event CancellationBurn(uint256 assets_, uint256 shares_);
event InstantWithdrawalFeeChanged(uint256 percentage_);
event LockTimeChanged(uint256 lockTime_);
event Redistribute(uint256 assets_);
event Refund(address indexed receiver_, uint256 assets_, uint256 shares_);
event WithdrawalFeeExemptionStatusChanged(address indexed account_, bool status_);
event WithdrawalFeePaid(address indexed caller_, address indexed receiver_, address indexed owner_, uint256 fee_);
event WithdrawalRequestCreated(WithdrawalRequest request_, uint256 pos_);
event WithdrawalRequestCancelled(uint256 pos_);
event WithdrawalRequestExecuted(uint256 pos_);
function MAXIMUM_LOCK_TIME() external view returns (uint256 maximumLockTime_);
function VESTING_PERIOD() external view returns (uint256 vestingPeriod_);
function WITHDRAWAL_WINDOW() external view returns (uint256 withdrawalWindow_);
function instantWithdrawalFee() external view returns (uint256 instantWithdrawalFee_);
function lockTime() external view returns (uint256 lockTime_);
function withdrawalFeeExemptions(address account_) external view returns (bool status_);
function setInstantWithdrawalFee(uint256 percentage_) external;
function setLockTime(uint256 lockTime_) external;
function setWithdrawalFeeExemption(address owner_, bool status_) external;
function createWithdrawalRequest(uint256 shares_) external;
function cancelWithdrawalRequest(uint256 pos_) external;
function executeWithdrawalRequest(uint256 pos_) external;
function updateVestingSchedule() external returns (uint256 issuanceRate_, uint256 freeAssets_);
function deposit(uint256 assets_, address receiver_, uint256 minShares_) external returns (uint256 shares_);
function mint(uint256 shares_, address receiver_, uint256 maxAssets_) external returns (uint256 assets_);
function redeem(uint256 shares_, address receiver_, address owner_, uint256 minAssets_)
external
returns (uint256 assets_);
function withdraw(uint256 assets_, address receiver_, address owner_, uint256 maxShares_)
external
returns (uint256 shares_);
function previewRedeem(uint256 shares_, address owner_) external view returns (uint256 assets_, uint256 fee_);
function previewWithdraw(uint256 assets_, address owner_) external view returns (uint256 shares_, uint256 fee_);
function previewWithdrawalRequest(uint256 pos_, address owner_)
external
view
returns (WithdrawalRequest memory request_, uint256 assets_, uint256 fee_);
function withdrawalRequestCount(address owner_) external view returns (uint256 count_);
function withdrawalRequests(address owner_) external view returns (WithdrawalRequest[] memory requests_);
function withdrawalRequests(address account_, uint256 pos_)
external
view
returns (WithdrawalRequest memory request_);
}
文件 9 的 12:IRevenueDistributionToken.sol
pragma solidity 0.8.7;
import { IERC20 } from "erc20/interfaces/IERC20.sol";
import { IERC4626 } from "./IERC4626.sol";
interface IRevenueDistributionToken is IERC20, IERC4626 {
event IssuanceParamsUpdated(uint256 freeAssets_, uint256 issuanceRate_);
event OwnershipAccepted(address indexed previousOwner_, address indexed newOwner_);
event PendingOwnerSet(address indexed owner_, address indexed pendingOwner_);
event VestingScheduleUpdated(address indexed owner_, uint256 vestingPeriodFinish_);
function freeAssets() external view returns (uint256 freeAssets_);
function issuanceRate() external view returns (uint256 issuanceRate_);
function lastUpdated() external view returns (uint256 lastUpdated_);
function owner() external view returns (address owner_);
function pendingOwner() external view returns (address pendingOwner_);
function precision() external view returns (uint256 precision_);
function vestingPeriodFinish() external view returns (uint256 vestingPeriodFinish_);
function acceptOwnership() external;
function setPendingOwner(address pendingOwner_) external;
function updateVestingSchedule(uint256 vestingPeriod_) external returns (uint256 issuanceRate_, uint256 freeAssets_);
function depositWithPermit(uint256 assets_, address receiver_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_) external returns (uint256 shares_);
function mintWithPermit(uint256 shares_, address receiver_, uint256 maxAssets_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_) external returns (uint256 assets_);
function balanceOfAssets(address account_) external view returns (uint256 assets_);
}
文件 10 的 12:LockedRevenueDistributionToken.sol
pragma solidity ^0.8.7;
import {RevenueDistributionToken} from "revenue-distribution-token/RevenueDistributionToken.sol";
import {ERC20} from "erc20/ERC20.sol";
import {ERC20Helper} from "erc20-helper/ERC20Helper.sol";
import {ILockedRevenueDistributionToken} from "./interfaces/ILockedRevenueDistributionToken.sol";
contract LockedRevenueDistributionToken is ILockedRevenueDistributionToken, RevenueDistributionToken {
uint256 public constant override MAXIMUM_LOCK_TIME = 104 weeks;
uint256 public constant override VESTING_PERIOD = 2 weeks;
uint256 public constant override WITHDRAWAL_WINDOW = 4 weeks;
uint256 public override instantWithdrawalFee;
uint256 public override lockTime;
mapping(address => WithdrawalRequest[]) internal userWithdrawalRequests;
mapping(address => bool) public override withdrawalFeeExemptions;
constructor(
string memory name_,
string memory symbol_,
address owner_,
address asset_,
uint256 precision_,
uint256 instantWithdrawalFee_,
uint256 lockTime_,
uint256 initialSeed_
) RevenueDistributionToken(name_, symbol_, owner_, asset_, precision_) {
instantWithdrawalFee = instantWithdrawalFee_;
lockTime = lockTime_;
if (initialSeed_ > 0) {
address caller_ = msg.sender;
address receiver_ = address(0);
totalSupply += initialSeed_;
unchecked {
balanceOf[receiver_] += initialSeed_;
}
emit Transfer(address(0), receiver_, initialSeed_);
freeAssets = initialSeed_;
emit Deposit(caller_, receiver_, initialSeed_, initialSeed_);
emit IssuanceParamsUpdated(freeAssets, 0);
require(ERC20Helper.transferFrom(asset_, msg.sender, address(this), initialSeed_), "LRDT:C:TRANSFER_FROM");
}
}
function setInstantWithdrawalFee(uint256 percentage_) external virtual override {
require(msg.sender == owner, "LRDT:CALLER_NOT_OWNER");
require(percentage_ < 100, "LRDT:INVALID_FEE");
instantWithdrawalFee = percentage_;
emit InstantWithdrawalFeeChanged(percentage_);
}
function setLockTime(uint256 lockTime_) external virtual override {
require(msg.sender == owner, "LRDT:CALLER_NOT_OWNER");
require(lockTime_ <= MAXIMUM_LOCK_TIME, "LRDT:INVALID_LOCK_TIME");
lockTime = lockTime_;
emit LockTimeChanged(lockTime_);
}
function setWithdrawalFeeExemption(address account_, bool status_) external virtual override {
require(msg.sender == owner, "LRDT:CALLER_NOT_OWNER");
require(account_ != address(0), "LRDT:ZERO_ACCOUNT");
if (status_) {
withdrawalFeeExemptions[account_] = true;
} else {
delete withdrawalFeeExemptions[account_];
}
emit WithdrawalFeeExemptionStatusChanged(account_, status_);
}
function createWithdrawalRequest(uint256 shares_) external virtual override nonReentrant {
require(shares_ > 0, "LRDT:INVALID_AMOUNT");
require(shares_ <= balanceOf[msg.sender], "LRDT:INSUFFICIENT_BALANCE");
WithdrawalRequest memory request_ = WithdrawalRequest(
uint32(block.timestamp + lockTime), uint32(lockTime), uint96(shares_), uint96(convertToAssets(shares_))
);
userWithdrawalRequests[msg.sender].push(request_);
_transfer(msg.sender, address(this), shares_);
emit WithdrawalRequestCreated(request_, userWithdrawalRequests[msg.sender].length - 1);
}
function cancelWithdrawalRequest(uint256 pos_) external virtual override nonReentrant {
WithdrawalRequest memory request_ = userWithdrawalRequests[msg.sender][pos_];
require(request_.shares > 0, "LRDT:NO_WITHDRAWAL_REQUEST");
delete userWithdrawalRequests[msg.sender][pos_];
uint256 refundShares_ = convertToShares(request_.assets);
uint256 burnShares_ = request_.shares - refundShares_;
if (burnShares_ > 0) {
uint256 burnAssets_ = convertToAssets(burnShares_);
_burn(burnShares_, burnAssets_, address(this), address(this), address(this));
emit Redistribute(burnAssets_);
}
if (refundShares_ > 0) {
_transfer(address(this), msg.sender, refundShares_);
emit Refund(msg.sender, convertToAssets(refundShares_), refundShares_);
}
emit WithdrawalRequestCancelled(pos_);
}
function executeWithdrawalRequest(uint256 pos_) external virtual override nonReentrant {
(WithdrawalRequest memory request_, uint256 assets_, uint256 fee_) = previewWithdrawalRequest(pos_, msg.sender);
require(request_.shares > 0, "LRDT:NO_WITHDRAWAL_REQUEST");
require(request_.unlockedAt + WITHDRAWAL_WINDOW > block.timestamp, "LRDT:WITHDRAWAL_WINDOW_CLOSED");
delete userWithdrawalRequests[msg.sender][pos_];
uint256 executeShares_ = convertToShares(assets_);
uint256 burnShares_ = request_.shares - executeShares_;
if (burnShares_ > 0) {
uint256 burnAssets_ = convertToAssets(burnShares_);
_burn(burnShares_, burnAssets_, address(this), address(this), address(this));
emit Redistribute(burnAssets_ - fee_);
}
if (executeShares_ > 0) {
_transfer(address(this), msg.sender, executeShares_);
_burn(executeShares_, assets_, msg.sender, msg.sender, msg.sender);
}
if (fee_ > 0) {
emit WithdrawalFeePaid(msg.sender, msg.sender, msg.sender, fee_);
}
emit WithdrawalRequestExecuted(pos_);
}
function updateVestingSchedule() external virtual override returns (uint256 issuanceRate_, uint256 freeAssets_) {
require(vestingPeriodFinish <= block.timestamp + 24 hours, "LRDT:UVS:STILL_VESTING");
require(totalSupply > 0, "LRDT:UVS:ZERO_SUPPLY");
freeAssets_ = (freeAssets = totalAssets());
uint256 vestingTime_ = VESTING_PERIOD;
if (vestingPeriodFinish > block.timestamp) {
vestingTime_ = VESTING_PERIOD + (vestingPeriodFinish - block.timestamp);
}
issuanceRate_ =
(issuanceRate = ((ERC20(asset).balanceOf(address(this)) - freeAssets_) * precision) / vestingTime_);
require(issuanceRate_ > 0, "LRDT:UVS:ZERO_ISSUANCE_RATE");
vestingPeriodFinish = (lastUpdated = block.timestamp) + vestingTime_;
emit IssuanceParamsUpdated(freeAssets_, issuanceRate_);
emit VestingScheduleUpdated(msg.sender, vestingPeriodFinish);
}
function deposit(uint256 assets_, address receiver_, uint256 minShares_)
external
virtual
override
returns (uint256 shares_)
{
shares_ = deposit(assets_, receiver_);
require(shares_ >= minShares_, "LRDT:D:SLIPPAGE_PROTECTION");
}
function mint(uint256 shares_, address receiver_, uint256 maxAssets_)
external
virtual
override
returns (uint256 assets_)
{
assets_ = mint(shares_, receiver_);
require(assets_ <= maxAssets_, "LRDT:M:SLIPPAGE_PROTECTION");
}
function redeem(uint256 shares_, address receiver_, address owner_)
public
virtual
override
nonReentrant
returns (uint256 assets_)
{
uint256 fee_;
(assets_, fee_) = previewRedeem(shares_, owner_);
_burn(shares_, assets_, receiver_, owner_, msg.sender);
if (fee_ > 0) {
emit WithdrawalFeePaid(msg.sender, receiver_, owner_, fee_);
}
}
function redeem(uint256 shares_, address receiver_, address owner_, uint256 minAssets_)
external
virtual
override
returns (uint256 assets_)
{
assets_ = redeem(shares_, receiver_, owner_);
require(assets_ >= minAssets_, "LRDT:R:SLIPPAGE_PROTECTION");
}
function withdraw(uint256 assets_, address receiver_, address owner_)
public
virtual
override
nonReentrant
returns (uint256 shares_)
{
uint256 fee_;
(shares_, fee_) = previewWithdraw(assets_, owner_);
_burn(shares_, assets_, receiver_, owner_, msg.sender);
if (fee_ > 0) {
emit WithdrawalFeePaid(msg.sender, receiver_, owner_, fee_);
}
}
function withdraw(uint256 assets_, address receiver_, address owner_, uint256 maxShares_)
external
virtual
override
returns (uint256 shares_)
{
shares_ = withdraw(assets_, receiver_, owner_);
require(shares_ <= maxShares_, "LRDT:W:SLIPPAGE_PROTECTION");
}
function previewRedeem(uint256 shares_) public view virtual override returns (uint256 assets_) {
(assets_,) = previewRedeem(shares_, address(0));
}
function previewRedeem(uint256 shares_, address owner_)
public
view
virtual
override
returns (uint256 assets_, uint256 fee_)
{
if (withdrawalFeeExemptions[owner_]) {
return (super.previewRedeem(shares_), 0);
}
uint256 assetsPlusFee_ = super.previewRedeem(shares_);
assets_ = (assetsPlusFee_ * (100 - instantWithdrawalFee)) / 100;
fee_ = assetsPlusFee_ - assets_;
}
function previewWithdraw(uint256 assets_) public view virtual override returns (uint256 shares_) {
(shares_,) = previewWithdraw(assets_, address(0));
}
function previewWithdraw(uint256 assets_, address owner_)
public
view
virtual
override
returns (uint256 shares_, uint256 fee_)
{
if (withdrawalFeeExemptions[owner_]) {
return (super.previewWithdraw(assets_), 0);
}
uint256 assetsPlusFee_ = (assets_ * 100) / (100 - instantWithdrawalFee);
shares_ = super.previewWithdraw(assetsPlusFee_);
fee_ = assetsPlusFee_ - assets_;
}
function previewWithdrawalRequest(uint256 pos_, address owner_)
public
view
virtual
override
returns (WithdrawalRequest memory request_, uint256 assets_, uint256 fee_)
{
request_ = userWithdrawalRequests[owner_][pos_];
if (withdrawalFeeExemptions[owner_] || request_.unlockedAt <= block.timestamp) {
return (request_, request_.assets, 0);
}
uint256 remainingTime_ = request_.unlockedAt - block.timestamp;
uint256 feePercentage_ = (instantWithdrawalFee * remainingTime_ * precision) / request_.lockTime;
assets_ = (request_.assets * (100 * precision - feePercentage_)) / (100 * precision);
fee_ = request_.assets - assets_;
}
function maxDeposit(address receiver_) external pure virtual override returns (uint256 maxAssets_) {
receiver_;
maxAssets_ = type(uint96).max;
}
function maxMint(address receiver_) external pure virtual override returns (uint256 maxShares_) {
receiver_;
maxShares_ = type(uint96).max;
}
function withdrawalRequestCount(address owner_) external view virtual override returns (uint256 count_) {
count_ = userWithdrawalRequests[owner_].length;
}
function withdrawalRequests(address owner_)
external
view
virtual
override
returns (WithdrawalRequest[] memory withdrawalRequests_)
{
withdrawalRequests_ = userWithdrawalRequests[owner_];
}
function withdrawalRequests(address account_, uint256 pos_)
external
view
virtual
override
returns (WithdrawalRequest memory withdrawalRequest_)
{
withdrawalRequest_ = userWithdrawalRequests[account_][pos_];
}
}
文件 11 的 12:Math.sol
pragma solidity ^0.8.7;
library Math {
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 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);
}
}
}
文件 12 的 12:RevenueDistributionToken.sol
pragma solidity 0.8.7;
import { ERC20 } from "erc20/ERC20.sol";
import { ERC20Helper } from "erc20-helper/ERC20Helper.sol";
import { IRevenueDistributionToken } from "./interfaces/IRevenueDistributionToken.sol";
contract RevenueDistributionToken is IRevenueDistributionToken, ERC20 {
uint256 public immutable override precision;
address public override asset;
address public override owner;
address public override pendingOwner;
uint256 public override freeAssets;
uint256 public override issuanceRate;
uint256 public override lastUpdated;
uint256 public override vestingPeriodFinish;
uint256 private locked = 1;
modifier nonReentrant() {
require(locked == 1, "RDT:LOCKED");
locked = 2;
_;
locked = 1;
}
constructor(string memory name_, string memory symbol_, address owner_, address asset_, uint256 precision_)
ERC20(name_, symbol_, ERC20(asset_).decimals())
{
require((owner = owner_) != address(0), "RDT:C:OWNER_ZERO_ADDRESS");
asset = asset_;
precision = precision_;
}
function acceptOwnership() external virtual override {
require(msg.sender == pendingOwner, "RDT:AO:NOT_PO");
emit OwnershipAccepted(owner, msg.sender);
owner = msg.sender;
pendingOwner = address(0);
}
function setPendingOwner(address pendingOwner_) external virtual override {
require(msg.sender == owner, "RDT:SPO:NOT_OWNER");
pendingOwner = pendingOwner_;
emit PendingOwnerSet(msg.sender, pendingOwner_);
}
function updateVestingSchedule(uint256 vestingPeriod_) external virtual override returns (uint256 issuanceRate_, uint256 freeAssets_) {
require(msg.sender == owner, "RDT:UVS:NOT_OWNER");
require(totalSupply != 0, "RDT:UVS:ZERO_SUPPLY");
freeAssets_ = freeAssets = totalAssets();
issuanceRate_ = issuanceRate = ((ERC20(asset).balanceOf(address(this)) - freeAssets_) * precision) / vestingPeriod_;
vestingPeriodFinish = (lastUpdated = block.timestamp) + vestingPeriod_;
emit IssuanceParamsUpdated(freeAssets_, issuanceRate_);
emit VestingScheduleUpdated(msg.sender, vestingPeriodFinish);
}
function deposit(uint256 assets_, address receiver_) public virtual override nonReentrant returns (uint256 shares_) {
_mint(shares_ = previewDeposit(assets_), assets_, receiver_, msg.sender);
}
function depositWithPermit(
uint256 assets_,
address receiver_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
)
external virtual override nonReentrant returns (uint256 shares_)
{
ERC20(asset).permit(msg.sender, address(this), assets_, deadline_, v_, r_, s_);
_mint(shares_ = previewDeposit(assets_), assets_, receiver_, msg.sender);
}
function mint(uint256 shares_, address receiver_) public virtual override nonReentrant returns (uint256 assets_) {
_mint(shares_, assets_ = previewMint(shares_), receiver_, msg.sender);
}
function mintWithPermit(
uint256 shares_,
address receiver_,
uint256 maxAssets_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
)
external virtual override nonReentrant returns (uint256 assets_)
{
require((assets_ = previewMint(shares_)) <= maxAssets_, "RDT:MWP:INSUFFICIENT_PERMIT");
ERC20(asset).permit(msg.sender, address(this), maxAssets_, deadline_, v_, r_, s_);
_mint(shares_, assets_, receiver_, msg.sender);
}
function redeem(uint256 shares_, address receiver_, address owner_) external virtual override nonReentrant returns (uint256 assets_) {
_burn(shares_, assets_ = previewRedeem(shares_), receiver_, owner_, msg.sender);
}
function withdraw(uint256 assets_, address receiver_, address owner_) external virtual override nonReentrant returns (uint256 shares_) {
_burn(shares_ = previewWithdraw(assets_), assets_, receiver_, owner_, msg.sender);
}
function _mint(uint256 shares_, uint256 assets_, address receiver_, address caller_) internal virtual {
require(receiver_ != address(0), "RDT:M:ZERO_RECEIVER");
require(shares_ != uint256(0), "RDT:M:ZERO_SHARES");
require(assets_ != uint256(0), "RDT:M:ZERO_ASSETS");
_mint(receiver_, shares_);
uint256 freeAssetsCache = freeAssets = totalAssets() + assets_;
uint256 issuanceRate_ = _updateIssuanceParams();
emit Deposit(caller_, receiver_, assets_, shares_);
emit IssuanceParamsUpdated(freeAssetsCache, issuanceRate_);
require(ERC20Helper.transferFrom(asset, caller_, address(this), assets_), "RDT:M:TRANSFER_FROM");
}
function _burn(uint256 shares_, uint256 assets_, address receiver_, address owner_, address caller_) internal virtual {
require(receiver_ != address(0), "RDT:B:ZERO_RECEIVER");
require(shares_ != uint256(0), "RDT:B:ZERO_SHARES");
require(assets_ != uint256(0), "RDT:B:ZERO_ASSETS");
if (caller_ != owner_) {
_decreaseAllowance(owner_, caller_, shares_);
}
_burn(owner_, shares_);
uint256 freeAssetsCache = freeAssets = totalAssets() - assets_;
uint256 issuanceRate_ = _updateIssuanceParams();
emit Withdraw(caller_, receiver_, owner_, assets_, shares_);
emit IssuanceParamsUpdated(freeAssetsCache, issuanceRate_);
require(ERC20Helper.transfer(asset, receiver_, assets_), "RDT:B:TRANSFER");
}
function _updateIssuanceParams() internal returns (uint256 issuanceRate_) {
return issuanceRate = (lastUpdated = block.timestamp) > vestingPeriodFinish ? 0 : issuanceRate;
}
function balanceOfAssets(address account_) public view virtual override returns (uint256 balanceOfAssets_) {
return convertToAssets(balanceOf[account_]);
}
function convertToAssets(uint256 shares_) public view virtual override returns (uint256 assets_) {
uint256 supply = totalSupply;
assets_ = supply == 0 ? shares_ : (shares_ * totalAssets()) / supply;
}
function convertToShares(uint256 assets_) public view virtual override returns (uint256 shares_) {
uint256 supply = totalSupply;
shares_ = supply == 0 ? assets_ : (assets_ * supply) / totalAssets();
}
function maxDeposit(address receiver_) external pure virtual override returns (uint256 maxAssets_) {
receiver_;
maxAssets_ = type(uint256).max;
}
function maxMint(address receiver_) external pure virtual override returns (uint256 maxShares_) {
receiver_;
maxShares_ = type(uint256).max;
}
function maxRedeem(address owner_) external view virtual override returns (uint256 maxShares_) {
maxShares_ = balanceOf[owner_];
}
function maxWithdraw(address owner_) external view virtual override returns (uint256 maxAssets_) {
maxAssets_ = balanceOfAssets(owner_);
}
function previewDeposit(uint256 assets_) public view virtual override returns (uint256 shares_) {
shares_ = convertToShares(assets_);
}
function previewMint(uint256 shares_) public view virtual override returns (uint256 assets_) {
uint256 supply = totalSupply;
assets_ = supply == 0 ? shares_ : _divRoundUp(shares_ * totalAssets(), supply);
}
function previewRedeem(uint256 shares_) public view virtual override returns (uint256 assets_) {
assets_ = convertToAssets(shares_);
}
function previewWithdraw(uint256 assets_) public view virtual override returns (uint256 shares_) {
uint256 supply = totalSupply;
shares_ = supply == 0 ? assets_ : _divRoundUp(assets_ * supply, totalAssets());
}
function totalAssets() public view virtual override returns (uint256 totalManagedAssets_) {
uint256 issuanceRate_ = issuanceRate;
if (issuanceRate_ == 0) return freeAssets;
uint256 vestingPeriodFinish_ = vestingPeriodFinish;
uint256 lastUpdated_ = lastUpdated;
uint256 vestingTimePassed =
block.timestamp > vestingPeriodFinish_ ?
vestingPeriodFinish_ - lastUpdated_ :
block.timestamp - lastUpdated_;
return ((issuanceRate_ * vestingTimePassed) / precision) + freeAssets;
}
function _divRoundUp(uint256 numerator_, uint256 divisor_) internal pure returns (uint256 result_) {
return (numerator_ / divisor_) + (numerator_ % divisor_ > 0 ? 1 : 0);
}
}
{
"compilationTarget": {
"src/GovernanceLockedRevenueDistributionToken.sol": "GovernanceLockedRevenueDistributionToken"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":contract-test-utils/=lib/erc20-helper/lib/contract-test-utils/contracts/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc20-helper/=lib/erc20-helper/src/",
":erc20/=lib/erc20/contracts/",
":forge-std/=lib/forge-std/src/",
":revenue-distribution-token/=lib/revenue-distribution-token/contracts/"
]
}
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"asset_","type":"address"},{"internalType":"uint256","name":"precision_","type":"uint256"},{"internalType":"uint256","name":"instantWithdrawalFee_","type":"uint256"},{"internalType":"uint256","name":"lockTime_","type":"uint256"},{"internalType":"uint256","name":"initialSeed_","type":"uint256"}],"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":"amount_","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assets_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"CancellationBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator_","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate_","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate_","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate_","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance_","type":"uint256"}],"name":"DelegateVotesChanged","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":"assets_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"percentage_","type":"uint256"}],"name":"InstantWithdrawalFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"freeAssets_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"issuanceRate_","type":"uint256"}],"name":"IssuanceParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockTime_","type":"uint256"}],"name":"LockTimeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner_","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner_","type":"address"}],"name":"OwnershipAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner_","type":"address"},{"indexed":true,"internalType":"address","name":"pendingOwner_","type":"address"}],"name":"PendingOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assets_","type":"uint256"}],"name":"Redistribute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver_","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner_","type":"address"},{"indexed":true,"internalType":"address","name":"recipient_","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner_","type":"address"},{"indexed":false,"internalType":"uint256","name":"vestingPeriodFinish_","type":"uint256"}],"name":"VestingScheduleUpdated","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":"assets_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account_","type":"address"},{"indexed":false,"internalType":"bool","name":"status_","type":"bool"}],"name":"WithdrawalFeeExemptionStatusChanged","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":"fee_","type":"uint256"}],"name":"WithdrawalFeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"WithdrawalRequestCancelled","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"unlockedAt","type":"uint32"},{"internalType":"uint32","name":"lockTime","type":"uint32"},{"internalType":"uint96","name":"shares","type":"uint96"},{"internalType":"uint96","name":"assets","type":"uint96"}],"indexed":false,"internalType":"struct ILockedRevenueDistributionToken.WithdrawalRequest","name":"request_","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"WithdrawalRequestCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"WithdrawalRequestExecuted","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"domainSeparator_","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_LOCK_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VESTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAWAL_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOfAssets","outputs":[{"internalType":"uint256","name":"balanceOfAssets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"cancelWithdrawalRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint32","name":"pos_","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromBlock_","type":"uint32"},{"internalType":"uint96","name":"votes_","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"blockNumber_","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"createWithdrawalRequest","outputs":[],"stateMutability":"nonpayable","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":"subtractedAmount_","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee_","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee_","type":"address"},{"internalType":"uint256","name":"nonce_","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":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"minShares_","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"depositWithPermit","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"executeWithdrawalRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint96","name":"votes_","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber_","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"totalSupply_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"blockNumber_","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"votes_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"blockNumber_","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"votes_","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"votes_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"addedAmount_","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"instantWithdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"issuanceRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"maxAssets_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"maxShares_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"maxShares_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"maxAssets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"maxAssets_","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"maxAssets_","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":"mintWithPermit","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"numCheckpoints_","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"precision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"uint256","name":"fee_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"uint256","name":"fee_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pos_","type":"uint256"},{"internalType":"address","name":"owner_","type":"address"}],"name":"previewWithdrawalRequest","outputs":[{"components":[{"internalType":"uint32","name":"unlockedAt","type":"uint32"},{"internalType":"uint32","name":"lockTime","type":"uint32"},{"internalType":"uint96","name":"shares","type":"uint96"},{"internalType":"uint96","name":"assets","type":"uint96"}],"internalType":"struct ILockedRevenueDistributionToken.WithdrawalRequest","name":"request_","type":"tuple"},{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"uint256","name":"fee_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"minAssets_","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"address","name":"owner_","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentage_","type":"uint256"}],"name":"setInstantWithdrawalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockTime_","type":"uint256"}],"name":"setLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner_","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"bool","name":"status_","type":"bool"}],"name":"setWithdrawalFeeExemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"totalManagedAssets_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"recipient_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateVestingSchedule","outputs":[{"internalType":"uint256","name":"issuanceRate_","type":"uint256"},{"internalType":"uint256","name":"freeAssets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vestingPeriod_","type":"uint256"}],"name":"updateVestingSchedule","outputs":[{"internalType":"uint256","name":"issuanceRate_","type":"uint256"},{"internalType":"uint256","name":"freeAssets_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userCheckpoints","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint96","name":"shares","type":"uint96"},{"internalType":"uint96","name":"assets","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingPeriodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"maxShares_","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets_","type":"uint256"},{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"address","name":"owner_","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalFeeExemptions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"withdrawalRequestCount","outputs":[{"internalType":"uint256","name":"count_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"withdrawalRequests","outputs":[{"components":[{"internalType":"uint32","name":"unlockedAt","type":"uint32"},{"internalType":"uint32","name":"lockTime","type":"uint32"},{"internalType":"uint96","name":"shares","type":"uint96"},{"internalType":"uint96","name":"assets","type":"uint96"}],"internalType":"struct ILockedRevenueDistributionToken.WithdrawalRequest[]","name":"withdrawalRequests_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint256","name":"pos_","type":"uint256"}],"name":"withdrawalRequests","outputs":[{"components":[{"internalType":"uint32","name":"unlockedAt","type":"uint32"},{"internalType":"uint32","name":"lockTime","type":"uint32"},{"internalType":"uint96","name":"shares","type":"uint96"},{"internalType":"uint96","name":"assets","type":"uint96"}],"internalType":"struct ILockedRevenueDistributionToken.WithdrawalRequest","name":"withdrawalRequest_","type":"tuple"}],"stateMutability":"view","type":"function"}]