ETH Price: $3,147.19 (+5.57%)

Transaction Decoder

Block:
22634262 at Jun-04-2025 10:31:35 PM +UTC
Transaction Fee:
0.000106891692087832 ETH $0.34
Gas Used:
46,604 Gas / 2.293616258 Gwei

Emitted Events:

497 PENDLE.Approval( owner=[Sender] 0x83a54addf93271204b0d78ce776944b8c6b3e5ba, spender=0x00000000...43aC78BA3, value=115792089237316195423570985008687907853269984665640564039457584007913129639935 )

Account State Difference:

  Address   Before After State Difference Code
(Titan Builder)
9.301466176799888734 Eth9.301494308665780914 Eth0.00002813186589218
0x80850712...61B8da827
0x83a54adD...8C6b3e5BA
0.00052276597827607 Eth
Nonce: 2
0.000415874286188238 Eth
Nonce: 3
0.000106891692087832

Execution Trace

PENDLE.approve( spender=0x000000000022D473030F116dDEE9F6B43aC78BA3, amount=115792089237316195423570985008687907853269984665640564039457584007913129639935 ) => ( True )
1
{"Address.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity \u003e=0.6.2 \u003c0.8.0;\n\n/**\n * @dev Collection of functions related
    to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n *
    ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a
    contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an
    externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a
    contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This
    method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n
    // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize
    (account) }\n return size \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity\u0027s `transfer`: sends `amount` wei to\n *
    `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the
    gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to
    receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using
    -soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not
    create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security
    -considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address
    payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n
     // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n
    require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call
    using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If
    `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns
    the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables
    .html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a
    contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall
    (address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\"
    );\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback
    revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data,
    string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n
    /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n
    *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function
    must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256
    value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\"
    );\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with
    `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function
    functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n
    require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to
    non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{
    value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address
    -functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function
    functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data,
    \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string
    -}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address
    target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address:
    static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) =
    target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address
    -functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target,
    data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string
    -}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall
    (address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address:
    delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) =
    target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool
    success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return
    returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n
     // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline
    -assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata
    ), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"},"IERC20
    .sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity \u003e=0.6.0 \u003c0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as
    defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply()
    external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address
    account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\n *\n
     * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer
    (address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will
    be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when
    {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n
    /**\n * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\n *\n * Returns a boolean value indicating
    whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone
    may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n *
    condition is to first reduce the spender\u0027s allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum
    /EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount)
    external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount`
    is then deducted from the caller\u0027s\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n
     *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool
    );\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that
    `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when
    the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval
    (address indexed owner, address indexed spender, uint256 value);\n}\n"},"IPENDLE.sol":{"content":"// SPDX-License-Identifier: MIT\n/*\n * MIT
    License\n * ===========\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated
    documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy,
    modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished
    to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or
    substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS
    OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n */\n\npragma solidity 0.7.6;\n\nimport \"./IERC20.sol\"
    ;\n\ninterface IPENDLE is IERC20 {\n function initiateConfigChanges(\n uint256 _emissionRateMultiplierNumerator,\n uint256
    _terminalInflationRateNumerator,\n address _liquidityIncentivesRecipient,\n bool _isBurningAllowed\n ) external;\n\n function
    increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n\n function decreaseAllowance(address spender, uint256
    subtractedValue) external returns (bool);\n\n function burn(uint256 amount) external returns (bool);\n\n function applyConfigChanges()
    external;\n\n function claimLiquidityEmissions() external returns (uint256 totalEmissions);\n\n function isPendleToken() external view
    returns (bool);\n\n function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n function startTime()
    external view returns (uint256);\n\n function configChangesInitiated() external view returns (uint256);\n\n function
    emissionRateMultiplierNumerator() external view returns (uint256);\n\n function terminalInflationRateNumerator() external view returns (uint256
    );\n\n function liquidityIncentivesRecipient() external view returns (address);\n\n function isBurningAllowed() external view returns (bool
    );\n\n function pendingEmissionRateMultiplierNumerator() external view returns (uint256);\n\n function pendingTerminalInflationRateNumerator
    () external view returns (uint256);\n\n function pendingLiquidityIncentivesRecipient() external view returns (address);\n\n function
    pendingIsBurningAllowed() external view returns (bool);\n}\n"},"PENDLE.sol":{"content":"/* solhint-disable const-name-snakecase*/\n// SPDX-License
    -Identifier: MIT\n/*\n * MIT License\n * ===========\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of
    this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation
    the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom
    the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be
    included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n */\npragma solidity 0.7.6
    ;\npragma experimental ABIEncoderV2;\n\nimport \"./IPENDLE.sol\";\nimport \"./Permissions.sol\";\nimport \"./Withdrawable.sol\";\nimport \"
    ./SafeMath.sol\";\n\n/**\n * @notice The mechanics for delegating votes to other accounts is adapted from Compound\n * https://github.com
    /compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol\n ***/\ncontract PENDLE is IPENDLE, Permissions, Withdrawable {\n
    using SafeMath for uint256;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32
    fromBlock;\n uint256 votes;\n }\n\n bool public constant override isPendleToken = true;\n string public constant name = \"Pendle\"
    ;\n string public constant symbol = \"PENDLE\";\n uint8 public constant decimals = 18;\n uint256 public override totalSupply;\n\n
    uint256 private constant TEAM_INVESTOR_ADVISOR_AMOUNT = 94917125 * 1e18;\n uint256 private constant ECOSYSTEM_FUND_TOKEN_AMOUNT = 46 * 1_000_000
    * 1e18;\n uint256 private constant PUBLIC_SALES_TOKEN_AMOUNT = 16582875 * 1e18;\n uint256 private constant INITIAL_LIQUIDITY_EMISSION =
    1200000 * 1e18;\n uint256 private constant CONFIG_DENOMINATOR = 1_000_000_000_000;\n uint256 private constant CONFIG_CHANGES_TIME_LOCK = 7
    days;\n uint256 public override emissionRateMultiplierNumerator;\n uint256 public override terminalInflationRateNumerator;\n address
    public override liquidityIncentivesRecipient;\n bool public override isBurningAllowed;\n uint256 public override
    pendingEmissionRateMultiplierNumerator;\n uint256 public override pendingTerminalInflationRateNumerator;\n address public override
    pendingLiquidityIncentivesRecipient;\n bool public override pendingIsBurningAllowed;\n uint256 public override configChangesInitiated;\n
    uint256 public override startTime;\n uint256 public lastWeeklyEmission;\n uint256 public lastWeekEmissionSent;\n\n mapping(address =\u003e
    mapping(address =\u003e uint256)) internal allowances;\n mapping(address =\u003e uint256) internal balances;\n mapping(address =\u003e
    address) public delegates;\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping(address =\u003e mapping(uint32
    =\u003e Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping(address =\u003e uint32) public
    numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract\u0027s domain\n bytes32 public constant DOMAIN_TYPEHASH =\n
    keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation
    struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce
    ,uint256 expiry)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping(address =\u003e uint256) public nonces
    ;\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(\n address indexed delegator,\n
     address indexed fromDelegate,\n address indexed toDelegate\n );\n\n /// @notice An event thats emitted when a delegate
    account\u0027s vote balance changes\n event DelegateVotesChanged(\n address indexed delegate,\n uint256 previousBalance,\n
    uint256 newBalance\n );\n\n event PendingConfigChanges(\n uint256 pendingEmissionRateMultiplierNumerator,\n uint256
    pendingTerminalInflationRateNumerator,\n address pendingLiquidityIncentivesRecipient,\n bool pendingIsBurningAllowed\n );\n\n
    event ConfigsChanged(\n uint256 emissionRateMultiplierNumerator,\n uint256 terminalInflationRateNumerator,\n address
    liquidityIncentivesRecipient,\n bool isBurningAllowed\n );\n\n /**\n * @notice Construct a new PENDLE token\n */\n
    constructor(\n address _governance,\n address pendleTeamTokens,\n address pendleEcosystemFund,\n address salesMultisig
    ,\n address _liquidityIncentivesRecipient\n ) Permissions(_governance) {\n require(\n pendleTeamTokens != address(0)
    \u0026\u0026\n pendleEcosystemFund != address(0) \u0026\u0026\n salesMultisig != address(0) \u0026\u0026\n
     _liquidityIncentivesRecipient != address(0),\n \"ZERO_ADDRESS\"\n );\n _mint(pendleTeamTokens,
    TEAM_INVESTOR_ADVISOR_AMOUNT);\n _mint(pendleEcosystemFund, ECOSYSTEM_FUND_TOKEN_AMOUNT);\n _mint(salesMultisig,
    PUBLIC_SALES_TOKEN_AMOUNT);\n _mint(_liquidityIncentivesRecipient, INITIAL_LIQUIDITY_EMISSION * 26);\n
    emissionRateMultiplierNumerator = (CONFIG_DENOMINATOR * 989) / 1000; // emission rate = 98.9% -\u003e 1.1% decay\n
    terminalInflationRateNumerator = 379848538; // terminal inflation rate = 2% =\u003e weekly inflation = 0.0379848538%\n
    liquidityIncentivesRecipient = _liquidityIncentivesRecipient;\n startTime = block.timestamp;\n lastWeeklyEmission =
    INITIAL_LIQUIDITY_EMISSION;\n lastWeekEmissionSent = 26; // already done liquidity emissions for the first 26 weeks\n }\n\n /**\n
    * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and
    is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may
    transfer tokens\n * @param amount The number of tokens that are approved\n * @return Whether or not the approval succeeded\n **/\n
    function approve(address spender, uint256 amount) external override returns (bool) {\n _approve(msg.sender, spender, amount);\n
    return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the
    destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n
    function transfer(address dst, uint256 amount) external override returns (bool) {\n _transfer(msg.sender, dst, amount);\n return true
    ;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n *
    @param dst The address of the destination account\n * @param amount The number of tokens to transfer\n * @return Whether or not the
    transfer succeeded\n */\n function transferFrom(\n address src,\n address dst,\n uint256 amount\n ) external
    override returns (bool) {\n _transfer(src, dst, amount);\n _approve(\n src,\n msg.sender,\n
    allowances[src][msg.sender].sub(amount, \"TRANSFER_EXCEED_ALLOWANCE\")\n );\n return true;\n }\n\n /**\n * @dev Increases
    the allowance granted to spender by the caller.\n * @param spender The address to increase the allowance from.\n * @param addedValue The
    amount allowance to add.\n * @return returns true if allowance has increased, otherwise false\n **/\n function increaseAllowance(address
    spender, uint256 addedValue)\n public\n override\n returns (bool)\n {\n _approve(msg.sender, spender, allowances[msg
    .sender][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Decreases the allowance granted to spender by the caller
    .\n * @param spender The address to reduce the allowance from.\n * @param subtractedValue The amount allowance to subtract.\n * @return
    Returns true if allowance has decreased, otherwise false.\n **/\n function decreaseAllowance(address spender, uint256 subtractedValue)\n
     public\n override\n returns (bool)\n {\n _approve(\n msg.sender,\n spender,\n
    allowances[msg.sender][spender].sub(subtractedValue, \"NEGATIVE_ALLOWANCE\")\n );\n return true;\n }\n\n /**\n * @dev Burns
    an amount of tokens from the msg.sender\n * @param amount The amount to burn\n * @return Returns true if the operation is successful\n
    **/\n function burn(uint256 amount) public override returns (bool) {\n require(isBurningAllowed, \"BURNING_NOT_ALLOWED\");\n _burn
    (msg.sender, amount);\n return true;\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of
    `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the
    funds\n * @return The number of tokens approved\n **/\n function allowance(address account, address spender) external view override
    returns (uint256) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Get the number of tokens held by the
    `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function
    balanceOf(address account) external view override returns (uint256) {\n return balances[account];\n }\n\n /**\n * @notice Gets the
    current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for
    `account`\n */\n function getCurrentVotes(address account) external view returns (uint256) {\n uint32 nCheckpoints =
    numCheckpoints[account];\n return nCheckpoints \u003e 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n *
    @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate
    (address delegatee) public {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to
    `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n
     * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA
    signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(\n address delegatee,\n uint256
    nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public {\n bytes32 domainSeparator =\n
     keccak256(\n abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))\n );\n bytes32
    structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked
    (\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0),
    \"INVALID_SIGNATURE\");\n require(nonce == nonces[signatory]++, \"INVALID_NONCE\");\n require(block.timestamp \u003c= expiry,
    \"SIGNATURE_EXPIRED\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Determine the prior number of votes for
    an account as of a block number\n * @dev Block number must be a finalized block or else\n this function will revert to prevent
    misinformation\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n
     * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint256 blockNumber
    )\n public\n view\n override\n returns (uint256)\n {\n require(blockNumber \u003c block.number,
    \"NOT_YET_DETERMINED\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n
     }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock \u003c= blockNumber) {\n
     return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if
    (checkpoints[account][0].fromBlock \u003e blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper =
    nCheckpoints - 1;\n while (upper \u003e lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n
     Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n
     } else if (cp.fromBlock \u003c blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n
     }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee)
    internal {\n address currentDelegate = delegates[delegator];\n uint256 delegatorBalance = balances[delegator];\n
    delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate
    , delegatee, delegatorBalance);\n }\n\n function _transfer(\n address src,\n address dst,\n uint256 amount\n )
    internal {\n require(src != address(0), \"SENDER_ZERO_ADDR\");\n require(dst != address(0), \"RECEIVER_ZERO_ADDR\");\n require
    (dst != address(this), \"SEND_TO_TOKEN_CONTRACT\");\n\n balances[src] = balances[src].sub(amount, \"TRANSFER_EXCEED_BALANCE\");\n
    balances[dst] = balances[dst].add(amount);\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst],
    amount);\n }\n\n function _approve(\n address src,\n address dst,\n uint256 amount\n ) internal virtual {\n
    require(src != address(0), \"OWNER_ZERO_ADDR\");\n require(dst != address(0), \"SPENDER_ZERO_ADDR\");\n\n allowances[src][dst] =
    amount;\n emit Approval(src, dst, amount);\n }\n\n function _moveDelegates(\n address srcRep,\n address dstRep,\n
     uint256 amount\n ) internal {\n if (srcRep != dstRep \u0026\u0026 amount \u003e 0) {\n if (srcRep != address(0)) {\n
     uint32 srcRepNum = numCheckpoints[srcRep];\n uint256 srcRepOld = srcRepNum \u003e 0 ? checkpoints[srcRep][srcRepNum - 1]
    .votes : 0;\n uint256 srcRepNew = srcRepOld.sub(amount);\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew
    );\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint256
    dstRepOld = dstRepNum \u003e 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint256 dstRepNew = dstRepOld.add(amount);\n
     _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(\n
    address delegatee,\n uint32 nCheckpoints,\n uint256 oldVotes,\n uint256 newVotes\n ) internal {\n uint32 blockNumber
    = safe32(block.number, \"BLOCK_NUM_EXCEED_32_BITS\");\n\n if (\n nCheckpoints \u003e 0 \u0026\u0026
    checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber\n ) {\n checkpoints[delegatee][nCheckpoints - 1].votes =
    newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n
    numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n
    function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\n require(n \u003c 2**32, errorMessage);\n
    return uint32(n);\n }\n\n function getChainId() internal pure returns (uint256) {\n uint256 chainId;\n assembly {\n
    chainId := chainid()\n }\n return chainId;\n }\n\n function initiateConfigChanges(\n uint256
    _emissionRateMultiplierNumerator,\n uint256 _terminalInflationRateNumerator,\n address _liquidityIncentivesRecipient,\n bool
    _isBurningAllowed\n ) external override onlyGovernance {\n require(_liquidityIncentivesRecipient != address(0), \"ZERO_ADDRESS\");\n
     pendingEmissionRateMultiplierNumerator = _emissionRateMultiplierNumerator;\n pendingTerminalInflationRateNumerator =
    _terminalInflationRateNumerator;\n pendingLiquidityIncentivesRecipient = _liquidityIncentivesRecipient;\n pendingIsBurningAllowed =
    _isBurningAllowed;\n emit PendingConfigChanges(\n _emissionRateMultiplierNumerator,\n _terminalInflationRateNumerator
    ,\n _liquidityIncentivesRecipient,\n _isBurningAllowed\n );\n configChangesInitiated = block.timestamp;\n
    }\n\n function applyConfigChanges() external override {\n require(configChangesInitiated != 0, \"UNINITIATED_CONFIG_CHANGES\");\n
    require(\n block.timestamp \u003e configChangesInitiated + CONFIG_CHANGES_TIME_LOCK,\n \"TIMELOCK_IS_NOT_OVER\"\n
    );\n\n _mintLiquidityEmissions(); // We must settle the pending liquidity emissions first, to make sure the weeks in the past follow the old
    configs\n\n emissionRateMultiplierNumerator = pendingEmissionRateMultiplierNumerator;\n terminalInflationRateNumerator =
    pendingTerminalInflationRateNumerator;\n liquidityIncentivesRecipient = pendingLiquidityIncentivesRecipient;\n isBurningAllowed =
    pendingIsBurningAllowed;\n configChangesInitiated = 0;\n emit ConfigsChanged(\n emissionRateMultiplierNumerator,\n
     terminalInflationRateNumerator,\n liquidityIncentivesRecipient,\n isBurningAllowed\n );\n }\n\n function
    claimLiquidityEmissions() external override returns (uint256 totalEmissions) {\n require(msg.sender == liquidityIncentivesRecipient,
    \"NOT_INCENTIVES_RECIPIENT\");\n totalEmissions = _mintLiquidityEmissions();\n }\n\n function _mintLiquidityEmissions() internal
    returns (uint256 totalEmissions) {\n uint256 _currentWeek = _getCurrentWeek();\n if (_currentWeek \u003c= lastWeekEmissionSent) {\n
     return 0;\n }\n for (uint256 i = lastWeekEmissionSent + 1; i \u003c= _currentWeek; i++) {\n if (i \u003c= 259)
    {\n lastWeeklyEmission = lastWeeklyEmission.mul(emissionRateMultiplierNumerator).div(\n CONFIG_DENOMINATOR\n
     );\n } else {\n lastWeeklyEmission = totalSupply.mul(terminalInflationRateNumerator).div(\n
     CONFIG_DENOMINATOR\n );\n }\n _mint(liquidityIncentivesRecipient, lastWeeklyEmission);\n
    totalEmissions = totalEmissions.add(lastWeeklyEmission);\n }\n lastWeekEmissionSent = _currentWeek;\n }\n\n // get current 1
    -indexed week id\n function _getCurrentWeek() internal view returns (uint256 weekId) {\n weekId = (block.timestamp - startTime) / (7 days
    ) + 1;\n }\n\n function _mint(address account, uint256 amount) internal {\n require(account != address(0), \"MINT_TO_ZERO_ADDR\");\n\n
     totalSupply = totalSupply.add(amount);\n balances[account] = balances[account].add(amount);\n emit Transfer(address(0),
    account, amount);\n }\n\n function _burn(address account, uint256 amount) internal {\n require(account != address(0),
    \"BURN_FROM_ZERO_ADDRESS\");\n\n uint256 accountBalance = balances[account];\n require(accountBalance \u003e= amount,
    \"BURN_EXCEED_BALANCE\");\n balances[account] = accountBalance.sub(amount);\n totalSupply = totalSupply.sub(amount);\n\n emit
    Transfer(account, address(0), amount);\n }\n}\n"},"Permissions.sol":{"content":"// SPDX-License-Identifier: MIT\n/*\n * MIT License\n *
    ===========\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation
    files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge,
    publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so,
    subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or
    substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS
    OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n */\npragma solidity 0.7.6;\n\nimport \"./IERC20.sol\"
    ;\n\nabstract contract Permissions {\n address public governance;\n address public pendingGovernance;\n address internal initializer;\n\n
     event GovernanceClaimed(address newGovernance, address previousGovernance);\n\n event TransferGovernancePending(address pendingGovernance
    );\n\n constructor(address _governance) {\n require(_governance != address(0), \"ZERO_ADDRESS\");\n initializer = msg.sender;\n
     governance = _governance;\n }\n\n modifier initialized() {\n require(initializer == address(0), \"NOT_INITIALIZED\");\n _
    ;\n }\n\n modifier onlyGovernance() {\n require(msg.sender == governance, \"ONLY_GOVERNANCE\");\n _;\n }\n\n /**\n *
    @dev Allows the pendingGovernance address to finalize the change governance process.\n */\n function claimGovernance() public {\n
    require(pendingGovernance == msg.sender, \"WRONG_GOVERNANCE\");\n emit GovernanceClaimed(pendingGovernance, governance);\n governance
    = pendingGovernance;\n pendingGovernance = address(0);\n }\n\n /**\n * @dev Allows the current governance to set the
    pendingGovernance address.\n * @param _governance The address to transfer ownership to.\n */\n function transferGovernance(address
    _governance) public onlyGovernance {\n require(_governance != address(0), \"ZERO_ADDRESS\");\n pendingGovernance = _governance;\n\n
     emit TransferGovernancePending(pendingGovernance);\n }\n}\n"},"SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma
    solidity \u003e=0.6.0 \u003c0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./SafeMath.sol\";\nimport \"./Address.sol\";\n\n/**\n * @title SafeERC20\n
    * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead
    revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a
    `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n
    */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to,
    uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function
    safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token
    .transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n *
    {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance}
    instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called
    when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n //
    \u0027safeIncreaseAllowance\u0027 and \u0027safeDecreaseAllowance\u0027\n // solhint-disable-next-line max-line-length\n require
    ((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n
    );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function
    safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this),
    spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address
    (this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token
    .approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a
    contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n
     * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n
     function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass
    Solidity\u0027s return data size checking mechanism, since\n // we\u0027re implementing it ourselves. We use {Address.functionCall} to
    perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call
    .\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length
    \u003e 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool
    )), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"},"SafeMath.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma
    solidity \u003e=0.6.0 \u003c0.8.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n *
    Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises
    an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the
    transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs,
    so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an
    overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256)
    {\n uint256 c = a + b;\n if (c \u003c a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the
    substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a,
    uint256 b) internal pure returns (bool, uint256) {\n if (b \u003e a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring
    \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin
    /openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n
     return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n *
    _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return
    (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division
    by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n
     if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers,
    reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n * Requirements:\n *\n * -
    Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n
    require(c \u003e= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned
    integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n *
    Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n
     require(b \u003c= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of
    two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n *\n * Requirements:\n
     *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a
    == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n
    /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero
    .\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas
    untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * -
    The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0,
    \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers.
    (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses
    a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining
    gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure
    returns (uint256) {\n require(b \u003e 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the
    subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION:
    This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use
    {trySub}.\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow
    .\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003c= a,
    errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom
    message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires
    allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to
    Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses
    an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n
     function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n
     return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n *
    reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for
    the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity\u0027s `%` operator. This
    function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming
    all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b,
    string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n return a % b;\n }\n}\n"}
    ,"Withdrawable.sol":{"content":"// SPDX-License-Identifier: MIT\n/*\n * MIT License\n * ===========\n *\n * Permission is hereby granted, free of
    charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software
    without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *
    copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The
    above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE
    IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE\n */\npragma solidity 0.7.6;\n\nimport \"./IERC20.sol\";\nimport \"./SafeERC20.sol\";\nimport \"./Permissions.sol\"
    ;\n\nabstract contract Withdrawable is Permissions {\n using SafeERC20 for IERC20;\n\n event EtherWithdraw(uint256 amount, address sendTo);\n
     event TokenWithdraw(IERC20 token, uint256 amount, address sendTo);\n\n /**\n * @dev Allows governance to withdraw Ether in a Pendle
    contract\n * in case of accidental ETH transfer into the contract.\n * @param amount The amount of Ether to withdraw.\n * @param
    sendTo The recipient address.\n */\n function withdrawEther(uint256 amount, address payable sendTo) external onlyGovernance {\n (bool
    success, ) = sendTo.call{value: amount}(\"\");\n require(success, \"WITHDRAW_FAILED\");\n emit EtherWithdraw(amount, sendTo);\n
    }\n\n /**\n * @dev Allows governance to withdraw all IERC20 compatible tokens in a Pendle\n * contract in case of accidental token
    transfer into the contract.\n * @param token IERC20 The address of the token contract.\n * @param amount The amount of IERC20 tokens to
    withdraw.\n * @param sendTo The recipient address.\n */\n function withdrawToken(\n IERC20 token,\n uint256 amount,\n
     address sendTo\n ) external onlyGovernance {\n token.safeTransfer(sendTo, amount);\n emit TokenWithdraw(token, amount, sendTo
    );\n }\n}\n"}}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX