Overview
ETH Balance
ETH Value
$0.00Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 137328131 | 15 days ago | IN | 0 ETH | 0.000000053407 | ||||
Set Proposer | 137327386 | 15 days ago | IN | 0 ETH | 0.000000059831 | ||||
Set Fee Multipli... | 137276064 | 16 days ago | IN | 0 ETH | 0.00000006959 | ||||
Set Enforced Opt... | 137276061 | 16 days ago | IN | 0 ETH | 0.000000079081 | ||||
Set Votes Reader | 137276058 | 16 days ago | IN | 0 ETH | 0.000000073514 | ||||
Set Peer | 137276055 | 16 days ago | IN | 0 ETH | 0.000000072869 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
137691801 | 6 days ago | 0.000137212145207 ETH | ||||
137691801 | 6 days ago | 0.000137212145207 ETH | ||||
137691801 | 6 days ago | 0.000164654574249 ETH | ||||
137691761 | 6 days ago | 0.000179318029809 ETH | ||||
137691761 | 6 days ago | 0.000343972604058 ETH | ||||
137691674 | 6 days ago | 0.000137212145207 ETH | ||||
137691674 | 6 days ago | 0.000137212145207 ETH | ||||
137691674 | 6 days ago | 0.000164654574249 ETH | ||||
137691643 | 6 days ago | 0.000137212145207 ETH | ||||
137691643 | 6 days ago | 0.000137212145207 ETH | ||||
137691643 | 6 days ago | 0.000164654574249 ETH | ||||
137691636 | 6 days ago | 0.000179318029809 ETH | ||||
137691636 | 6 days ago | 0.000343972604058 ETH | ||||
137691604 | 6 days ago | 0.000179318029809 ETH | ||||
137691604 | 6 days ago | 0.000343972604058 ETH | ||||
137691276 | 6 days ago | 0.000137212145207 ETH | ||||
137691276 | 6 days ago | 0.000137212145207 ETH | ||||
137691276 | 6 days ago | 0.000164654574249 ETH | ||||
137691262 | 6 days ago | 0.000137212145207 ETH | ||||
137691262 | 6 days ago | 0.000137212145207 ETH | ||||
137691262 | 6 days ago | 0.000164654574249 ETH | ||||
137691235 | 6 days ago | 0.000179318029809 ETH | ||||
137691235 | 6 days ago | 0.000343972604058 ETH | ||||
137691225 | 6 days ago | 0.000137212145207 ETH | ||||
137691225 | 6 days ago | 0.000137212145207 ETH |
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { GovernorOVoteSide, VoteParam, OptionsParam, VoteFee } from "@layerzerolabs/governance-evm-contracts/contracts/GovernorOVoteSide.sol"; import { GovernorCountingSimple } from "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol"; import { GovernorOVoteBase } from "@layerzerolabs/governance-evm-contracts/contracts/GovernorOVoteBase.sol"; import { LzFeeSwitchGovernorBase } from "./LzFeeSwitchGovernorBase.sol"; import { IVoteMessaging } from "../interfaces/IVoteMessaging.sol"; import { IVotePower } from "../interfaces/IVotePower.sol"; /** * @title LzFeeSwitchGovernorSide * @dev This contract extends the functionality of LzFeeSwitchGovernorBase and GovernorOVoteSide. * It implements the IVoteMessaging and IVotePower interfaces to provide voting and messaging capabilities. */ contract LzFeeSwitchGovernorSide is LzFeeSwitchGovernorBase, GovernorOVoteSide, IVoteMessaging, IVotePower { // =============================== Struct =============================== /// @dev Struct to store the voting proposal info. struct Proposal { uint256 proposalId; uint64 snapshot; // snapshot timestamp, equal to voteStart uint64 deadline; // deadline timestamp } // =============================== Variables =============================== /// @dev The current voting proposal. Proposal public votingProposal; // =============================== Modifiers =============================== /** * @dev Modifier to restrict access to only the valid voting proposal. */ modifier validVotingProposal() { if (votingProposal.proposalId == 0) revert ErrInvalidVotingProposal(); uint256 currentTime = clock(); // snapshot is the start of the voting period if (currentTime < votingProposal.snapshot || currentTime > votingProposal.deadline) revert ErrOutOfVotingPeriod(); _; } /** * @dev Initializes the contract with the given parameters. * @param _endpoint The address of the LayerZero endpoint. * @param _mainEid The main chain EID. * @param _vote The address of the vote contract. */ constructor( address _endpoint, uint32 _mainEid, address _vote ) GovernorOVoteSide(_endpoint, msg.sender, _mainEid) LzFeeSwitchGovernorBase(_vote) {} // =============================== Proposer =============================== /** * @notice Set the voting proposal * @param _proposal The proposal to be voted */ function setVotingProposal(Proposal memory _proposal) external onlyProposer { votingProposal = _proposal; } // ============================ IVotePower ============================ /** * @notice Quotes the fee required to cast a vote on a proposal. * @dev This function calculates the lzRead and messaging fee required to cast a vote on the current voting proposal. * @return fee The calculated messaging fee. */ function quoteVote() external view validVotingProposal returns (MessagingFee memory fee) { VoteFee memory voteFee = _quoteCastVote( address(0), VoteParam( uint8(GovernorCountingSimple.VoteType.For), "", "", votingProposal.proposalId, votingProposal.snapshot ), OptionsParam("", ""), false ); fee = MessagingFee(voteFee.readNativeFee + voteFee.messagingNativeFee, voteFee.readLzTokenFee); } /** * @notice Casts a vote on the current voting proposal. * @dev This function is called by the vote contract to cast a vote on the current proposal. * @param _voter The address of the voter. * @param _enabledFeeSwitch A boolean indicating whether the fee switch is enabled. */ function vote(address _voter, bool _enabledFeeSwitch) external payable validVotingProposal onlyVote { Proposal memory proposal = votingProposal; uint8 support = _enabledFeeSwitch ? uint8(GovernorCountingSimple.VoteType.For) : uint8(GovernorCountingSimple.VoteType.Against); _lzCastVote( _voter, VoteParam(support, "", "", proposal.proposalId, proposal.snapshot), OptionsParam("", ""), VoteFee(msg.value, 0, 0) ); // update sent votes count castVoteSentCount[proposal.proposalId]++; hasSentVote[proposal.proposalId][_voter] = true; } /** * @notice Casting votes on arbitrary proposals is not allowed. */ function quoteCastVote( address /*_voter*/, VoteParam calldata /*_voteParam*/, OptionsParam calldata /*_options*/, bool /*_payInLzToken*/ ) public view virtual override returns (VoteFee memory) { revert ErrNotSupported(); } /** * @notice Casting votes on arbitrary proposals is not allowed. */ function lzCastVote( VoteParam calldata /*_voteParam*/, OptionsParam calldata /*_options*/, VoteFee calldata /*_fee*/ ) external payable virtual override { revert ErrNotSupported(); } // ============================ IVoteMessaging ============================ function sendBallot(Ballot memory /*_ballot*/) external payable { revert ErrNotSupported(); } /** * @notice Quotes the fee required to commit a vote on the current voting proposal. * @dev This function calculates the messaging fee required to send a ballot. * @return fee The calculated messaging fee. */ function quoteSendBallot() external view returns (MessagingFee memory fee) { fee = _quoteSubmitVote( address(0), VoteParam( uint8(GovernorCountingSimple.VoteType.For), "", "", votingProposal.proposalId, votingProposal.snapshot ), 0, "" ); } // ============================== Internal Override ============================== /** * @notice Handles the fee required for casting a vote. * @dev This function calculates and verifies the lzRead and messaging fee required to cast a vote. * It reverts if the provided fee is insufficient. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _optionsParam The options parameters for the vote. * @param /*_fee*\/ The fee provided for the vote. * @return voteFee The calculated vote fee. */ function _handleVoteFee( address _voter, VoteParam memory _voteParam, OptionsParam memory _optionsParam, VoteFee memory /*_fee*/ ) internal override returns (VoteFee memory voteFee) { MessagingFee memory expectedMessagingFee = _quoteSubmitVote( _voter, _voteParam, 0, _optionsParam.messagingOptions ); if (msg.value < expectedMessagingFee.nativeFee) { revert InsufficientMessagingFee(msg.value, expectedMessagingFee.nativeFee); } voteFee.readNativeFee = msg.value - expectedMessagingFee.nativeFee; voteFee.messagingNativeFee = expectedMessagingFee.nativeFee; } // ========================== The functions below are overrides required by Solidity ========================== function clock() public view virtual override(GovernorOVoteBase, LzFeeSwitchGovernorBase) returns (uint48) { return super.clock(); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { IERC6372 } from "@openzeppelin/contracts/interfaces/IERC6372.sol"; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { OAppCore } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppReceiver.sol"; import { IVotesReadCallback, IVotesReader } from "./votes-reader/IVotesReader.sol"; /** * @title GovernorOVoteBase * @dev Abstract contract for handling vote-related operations in a governance system. */ abstract contract GovernorOVoteBase is OAppCore, IVotesReadCallback, IERC6372 { using SafeCast for uint256; using SafeERC20 for IERC20; // =============================== Structs =============================== /** * @dev Struct representing the data for a vote message. * @param proposalId The ID of the proposal being voted on. * @param voter The address of the voter. * @param castVoteTime The time the vote was cast. * @param support The support value for the vote. * @param reason The reason for the vote. * @param params Additional parameters for the vote. * @param snapshot The snapshot timestamp for the vote. * @param votes The number of votes. */ struct MsgData { uint256 proposalId; address voter; uint64 castVoteTime; uint8 support; string reason; bytes params; uint64 snapshot; uint256 votes; } // =============================== Events =============================== event LzVoteCast(address indexed voter, uint256 indexed proposalId, uint8 support, string reason, bytes params); // =============================== Errors =============================== // @dev Error thrown when an unauthorized action is attempted. error Unauthorized(); // @dev Error thrown when there is a read request in progress. error ReadRequestInProgress(); // =============================== Variables =============================== /** * @dev The contract for reading votes. */ IVotesReader public votesReader; uint256 internal inflightReadRequests; // =============================== Modifiers =============================== /** * @dev Modifier to restrict access to the votes reader. */ modifier onlyVotesReader() { if (_msgSender() != address(votesReader)) revert Unauthorized(); _; } /** * @dev Constructor to initialize the contract. * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The address of the delegate. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} // =============================== Setters =============================== /** * @notice Sets the votes reader contract. * @param _votesReaderContract The address of the votes reader contract. */ function setVotesReader(address _votesReaderContract) external virtual onlyOwner { if (inflightReadRequests > 0) revert ReadRequestInProgress(); votesReader = IVotesReader(_votesReaderContract); } // =============================== VotesReader Callbacks =============================== /** * @notice Callback function called when votes are received. * @param _voter The address of the voter. * @param _snapshot The snapshot timestamp. * @param _votes The number of votes received. * @param _extraData Additional data. */ function onVotesReceived( address _voter, uint64 _snapshot, uint256 _votes, bytes calldata _extraData ) external payable virtual onlyVotesReader { inflightReadRequests--; _onVotesReceived(_voter, _snapshot, _votes, _extraData); } /** * @dev Internal function to handle received votes. * @param _voter The address of the voter. * @param _snapshot The snapshot timestamp. * @param _votes The number of votes received. * @param _extraData Additional data. */ function _onVotesReceived( address _voter, uint64 _snapshot, uint256 _votes, bytes calldata _extraData ) internal virtual; // =============================== Internal Helpers =============================== /** * @dev Internal function to handle the payment of LayerZero token fee. * lzTokenFee will be transferred to the endpoint directly to save gas. * @param _lzTokenFee The LayerZero token fee. */ function _payLzTokenFee(uint256 _lzTokenFee) internal virtual { if (_lzTokenFee > 0) { address lzToken = endpoint.lzToken(); IERC20(lzToken).safeTransferFrom(_msgSender(), address(endpoint), _lzTokenFee); } } // =============================== EIP-6372 =============================== /** * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token * does not implement EIP-6372. * @return The current timestamp as a 48-bit integer. */ function clock() public view virtual override returns (uint48) { return block.timestamp.toUint48(); } /** * @dev Machine-readable description of the clock as specified in EIP-6372. * @return A string describing the clock mode. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory) { return "mode=timestamp&from=default"; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { BytesLib } from "solidity-bytes-utils/contracts/BytesLib.sol"; import { MessagingParams, MessagingFee, MessagingReceipt, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { OAppSender } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppSender.sol"; import { OAppOptionsType3 } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OAppOptionsType3.sol"; import { GovernorOVoteBase } from "./GovernorOVoteBase.sol"; import { IGovernorOVoteSide, OptionsParam, VoteParam, VoteFee } from "./interfaces/IGovernorOVoteSide.sol"; /** * @title GovernorOVoteSide * @dev Contract for handling cross-chain voting on the side chain. */ contract GovernorOVoteSide is OAppSender, GovernorOVoteBase, OAppOptionsType3, IGovernorOVoteSide { using BytesLib for bytes; // =============================== Errors =============================== /** * @dev Error thrown when the provided native fee does not match the expected fee. * @param provided The provided fee. * @param expected The expected fee. */ error NativeFeeNotMatch(uint256 provided, uint256 expected); /** * @dev Error thrown when the provided messaging fee is insufficient. * @param provided The provided fee. * @param expected The expected fee. */ error InsufficientMessagingFee(uint256 provided, uint256 expected); // =============================== Struct =============================== /** * @dev Struct representing the parameters for submitting a vote. * @param voter The address of the voter. * @param castVoteTime The time the vote was cast. * @param proposalId The ID of the proposal. * @param voteParam The parameters of the vote. * @param votes The number of votes. * @param messagingOptions The messaging options. * @param messagingNativeFee The native fee for messaging. * @param refundAddress The address to refund any excess fee. */ struct SubmitVoteParam { address voter; uint64 castVoteTime; uint256 proposalId; VoteParam voteParam; uint256 votes; bytes messagingOptions; uint256 messagingNativeFee; address refundAddress; } // =============================== State Variables =============================== /** * @dev Constant representing the vote type. */ uint8 internal constant TYPE_VOTE = 1; /** * @dev The main chain ID. */ uint32 public immutable mainEid; /** * @dev The multiplier basis points for the messaging fee. * Since read-then-vote is asynchronous, we increase the fee to absorb gas price fluctuations for vote */ uint16 public feeMultiplierBps; /** * @dev Constructor to initialize the contract. * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The address of the delegate. * @param _mainEid The main chain ID. */ constructor(address _endpoint, address _delegate, uint32 _mainEid) GovernorOVoteBase(_endpoint, _delegate) { mainEid = _mainEid; } // =============================== Setters =============================== /** * @notice Sets the messaging fee multiplier basis points. * @param _bps The basis points. */ function setFeeMultiplierBps(uint16 _bps) external virtual onlyOwner { feeMultiplierBps = _bps; } // =============================== IGovernorOVoteSide =============================== /** * @notice Quotes the fee required to cast a vote. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _options The options for the vote. * @param _payInLzToken A boolean indicating whether to pay in LzToken. * @return fee The calculated vote fee. */ function quoteCastVote( address _voter, VoteParam calldata _voteParam, OptionsParam calldata _options, bool _payInLzToken ) public view virtual returns (VoteFee memory fee) { return _quoteCastVote(_voter, _voteParam, _options, _payInLzToken); } /** * @notice Casts a vote using LayerZero messaging. * @param _voteParam The parameters of the vote. * @param _options The options for the vote. * @param _fee The fee for the vote. */ function lzCastVote( VoteParam calldata _voteParam, OptionsParam calldata _options, VoteFee calldata _fee ) external payable virtual { _lzCastVote(_msgSender(), _voteParam, _options, _fee); } // =============================== Internal =============================== /** * @dev Internal function to quote the fee required to cast a vote. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _options The options for the vote. * @param _payInLzToken A boolean indicating whether to pay in LzToken. * @return fee The calculated vote fee. */ function _quoteCastVote( address _voter, VoteParam memory _voteParam, OptionsParam memory _options, bool _payInLzToken ) internal view virtual returns (VoteFee memory fee) { bytes memory votingContext = _encodeVotingContext( clock(), _voteParam.proposalId, _voteParam, _combineOptions(enforcedOptions[mainEid][TYPE_VOTE], _options.messagingOptions), 0 ); MessagingFee memory readFee = votesReader.quote( _voter, _voteParam.snapshot, votingContext, _options.readOptions, _payInLzToken ); MessagingFee memory messagingFee = _quoteSubmitVote(_voter, _voteParam, 0, _options.messagingOptions); fee = VoteFee({ readNativeFee: readFee.nativeFee, readLzTokenFee: readFee.lzTokenFee, messagingNativeFee: messagingFee.nativeFee }); } /** * @dev Internal function to quote the fee for submitting a vote. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _votes The number of votes. * @param _messagingOptions The messaging options. * @return fee The calculated messaging fee. */ function _quoteSubmitVote( address _voter, VoteParam memory _voteParam, uint256 _votes, bytes memory _messagingOptions ) internal view virtual returns (MessagingFee memory fee) { bytes memory message = _encodeMessage( MsgData({ proposalId: _voteParam.proposalId, voter: _voter, castVoteTime: clock(), support: _voteParam.support, reason: _voteParam.reason, params: _voteParam.params, snapshot: _voteParam.snapshot, votes: _votes }) ); bytes memory options = _combineOptions(enforcedOptions[mainEid][TYPE_VOTE], _messagingOptions); // pay in lzToken is not allowed, as it cannot retry if lzReceive fails due to insufficient lzToken fees fee = _quote(mainEid, message, options, false); fee.nativeFee += (fee.nativeFee * feeMultiplierBps) / 10000; } /** * @dev Internal function to cast a vote using LayerZero messaging. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _optionsParam The options for the vote. * @param _fee The fee for the vote. */ function _lzCastVote( address _voter, VoteParam memory _voteParam, OptionsParam memory _optionsParam, VoteFee memory _fee ) internal virtual { _fee = _handleVoteFee(_voter, _voteParam, _optionsParam, _fee); _payLzTokenFee(_fee.readLzTokenFee); bytes memory votingContext = _encodeVotingContext( clock(), _voteParam.proposalId, _voteParam, _combineOptions(enforcedOptions[mainEid][TYPE_VOTE], _optionsParam.messagingOptions), _fee.messagingNativeFee ); votesReader.readVotes{ value: _fee.readNativeFee }( _voter, _voteParam.snapshot, votingContext, _optionsParam.readOptions, MessagingFee(_fee.readNativeFee, _fee.readLzTokenFee), _voter ); inflightReadRequests++; emit LzVoteCast(_voter, _voteParam.proposalId, _voteParam.support, _voteParam.reason, _voteParam.params); } /** * @dev Internal function to handle received votes. * @param _voter The address of the voter. * @param *_snapshot* The snapshot timestamp. * @param _votes The number of votes received. * @param _extraData Additional data. */ function _onVotesReceived( address _voter, uint64 /*_snapshot*/, uint256 _votes, bytes calldata _extraData ) internal virtual override { ( uint64 castVoteTime, uint256 proposalId, VoteParam memory voteParam, bytes memory messagingOptions, uint256 messagingNativeFee ) = _decodeVotingContext(_extraData); _submitVote( SubmitVoteParam( _voter, castVoteTime, proposalId, voteParam, _votes, messagingOptions, // If lzReceive fails due to insufficient native fees, user can retry by sending more native fees(msg.value) messagingNativeFee + msg.value, _voter ) ); } /** * @dev Internal function to handle the vote fee. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _optionsParam The options for the vote. * @param _fee The fee for the vote. * @return The handled vote fee. */ function _handleVoteFee( address _voter, VoteParam memory _voteParam, OptionsParam memory _optionsParam, VoteFee memory _fee ) internal virtual returns (VoteFee memory) { uint256 expectedNativeFee = _fee.readNativeFee + _fee.messagingNativeFee; if (msg.value != expectedNativeFee) { revert NativeFeeNotMatch(msg.value, expectedNativeFee); } MessagingFee memory expectedMessagingFee = _quoteSubmitVote( _voter, _voteParam, 0, _optionsParam.messagingOptions ); if (_fee.messagingNativeFee < expectedMessagingFee.nativeFee) { revert InsufficientMessagingFee(_fee.messagingNativeFee, expectedMessagingFee.nativeFee); } return _fee; } /** * @dev Internal function to submit a vote. * @param _param The parameters for submitting the vote. * @return receipt The messaging receipt. */ function _submitVote(SubmitVoteParam memory _param) internal virtual returns (MessagingReceipt memory receipt) { bytes memory message = _encodeMessage( MsgData({ proposalId: _param.proposalId, voter: _param.voter, castVoteTime: _param.castVoteTime, support: _param.voteParam.support, reason: _param.voteParam.reason, params: _param.voteParam.params, snapshot: _param.voteParam.snapshot, votes: _param.votes }) ); uint256 preBalance = address(this).balance; receipt = endpoint.send{ value: _param.messagingNativeFee }( // pay in lzToken is not allowed, as it cannot retry if lzReceive fails due to insufficient lzToken fees. MessagingParams(mainEid, _getPeerOrRevert(mainEid), message, _param.messagingOptions, false), address(this) ); uint256 feeRefund = address(this).balance + _param.messagingNativeFee - preBalance; if (feeRefund > 0) { // If refund fails, send the refund to tx.origin (the executor EOA) bool success = payable(_param.refundAddress).send(feeRefund); if (!success) { payable(tx.origin).transfer(feeRefund); } } } // =============================== Internal Utils =============================== /** * @dev Internal function to combine two sets of options. * @param _option1 The first set of options. * @param _option2 The second set of options. * @return The combined options. */ function _combineOptions( bytes memory _option1, bytes memory _option2 ) internal pure virtual returns (bytes memory) { if (_option1.length == 0) return _option2; if (_option2.length == 0) return _option1; if (_option1.length < 2 || _option2.length < 2) revert InvalidOptions(_option1.length < 2 ? _option1 : _option2); _assertOptionsType3(_option1); _assertOptionsType3(_option2); return bytes.concat(_option1, _option2.slice(2, _option2.length - 2)); } /** * @dev Internal function to encode the voting context. * @param _castVoteTime The time the vote was cast. * @param _proposalId The ID of the proposal. * @param _voteParam The parameters of the vote. * @param _messagingOptions The messaging options. * @param _messagingNativeFee The native fee for messaging. * @return The encoded voting context. */ function _encodeVotingContext( uint64 _castVoteTime, uint256 _proposalId, VoteParam memory _voteParam, bytes memory _messagingOptions, uint256 _messagingNativeFee ) internal view virtual returns (bytes memory) { return abi.encode(_castVoteTime, _proposalId, _voteParam, _messagingOptions, _messagingNativeFee); } /** * @dev Internal function to decode the voting context. * @param _context The encoded voting context. * @return The decoded voting context. */ function _decodeVotingContext( bytes memory _context ) internal pure virtual returns (uint64, uint256, VoteParam memory, bytes memory, uint256) { return abi.decode(_context, (uint64, uint256, VoteParam, bytes, uint256)); } /** * @dev Internal function to encode a cross chain message. * @param _msgData The message data. * @return The encoded message. */ function _encodeMessage(MsgData memory _msgData) internal pure virtual returns (bytes memory) { return abi.encode(_msgData); } // accept ether for endpoint refund fee receive() external payable {} }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /** * @dev Struct representing the parameters for a vote. * @param support The support value for the vote. * @param reason The reason for the vote. * @param params Additional parameters for the vote. * @param proposalId The ID of the proposal being voted on. * @param snapshot The snapshot for the vote. */ struct VoteParam { uint8 support; string reason; bytes params; uint256 proposalId; uint64 snapshot; } /** * @dev Struct representing the fees for a vote. * @param readNativeFee The native fee for reading. * @param readLzTokenFee The LayerZero token fee for reading. * @param messagingNativeFee The native fee for messaging. */ struct VoteFee { uint256 readNativeFee; uint256 readLzTokenFee; uint256 messagingNativeFee; } /** * @dev Struct representing the options for a vote. * @param readOptions The options for reading. * @param messagingOptions The options for messaging. */ struct OptionsParam { bytes readOptions; bytes messagingOptions; } /** * @title IGovernorOVoteSide * @dev Interface for the Governor OVote side contract. */ interface IGovernorOVoteSide { /** * @notice Quotes the fee required to cast a vote. * @param _voter The address of the voter. * @param _voteParam The parameters of the vote. * @param _options The options for the vote. * @param _payInLzToken A boolean indicating whether to pay in LzToken. * @return fee The calculated vote fee. */ function quoteCastVote( address _voter, VoteParam calldata _voteParam, OptionsParam calldata _options, bool _payInLzToken ) external view returns (VoteFee memory fee); /** * @notice Casts a vote. * @param _voteParam The parameters of the vote. * @param _options The options for the vote. * @param _fee The fee for the vote. */ function lzCastVote( VoteParam calldata _voteParam, OptionsParam calldata _options, VoteFee calldata _fee ) external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IVotesReadCallback * @dev Interface for the callback function to handle received votes. */ interface IVotesReadCallback { /** * @notice Called when votes are received. * @param _voter The address of the voter. * @param _snapshot The snapshot timestamp/block number. * @param _votes The number of votes received. * @param _extraData Additional data. */ function onVotesReceived( address _voter, uint64 _snapshot, uint256 _votes, bytes calldata _extraData ) external payable; } /** * @title IVotesReader * @dev Interface for reading votes and quoting the fee for reading votes. */ interface IVotesReader { /** * @notice Quotes the fee required to read votes. * @param _voter The address of the voter. * @param _snapshot The snapshot block number. * @param _extraData Additional data. * @param _options Additional options for the read operation. * @param _payInLzToken A boolean indicating whether to pay in LzToken. * @return The calculated messaging fee. */ function quote( address _voter, uint64 _snapshot, bytes calldata _extraData, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); /** * @notice Reads votes and sends a read request. * @param _voter The address of the voter. * @param _snapshot The snapshot block number. * @param _extraData Additional data. * @param _options Additional options for the read operation. * @param _fee The fee for the read operation. * @param _refundAddress The address to refund any excess fee. * @return The messaging receipt. */ function readVotes( address _voter, uint64 _snapshot, bytes calldata _extraData, bytes calldata _options, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol"; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { MessagingParams, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppOptionsType3, EnforcedOptionParam } from "../interfaces/IOAppOptionsType3.sol"; /** * @title OAppOptionsType3 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options. */ abstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable { uint16 internal constant OPTION_TYPE_3 = 3; // @dev The "msgType" should be defined in the child contract. mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions; /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner { _setEnforcedOptions(_enforcedOptions); } /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual { for (uint256 i = 0; i < _enforcedOptions.length; i++) { // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining. _assertOptionsType3(_enforcedOptions[i].options); enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options; } emit EnforcedOptionSet(_enforcedOptions); } /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OAPP message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. * * @dev If there is an enforced lzReceive option: * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether} * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function. * @dev This presence of duplicated options is handled off-chain in the verifier/executor. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) public view virtual returns (bytes memory) { bytes memory enforced = enforcedOptions[_eid][_msgType]; // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options. if (enforced.length == 0) return _extraOptions; // No caller options, return enforced if (_extraOptions.length == 0) return enforced; // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined. if (_extraOptions.length >= 2) { _assertOptionsType3(_extraOptions); // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced. return bytes.concat(enforced, _extraOptions[2:]); } // No valid set of options was found. revert InvalidOptions(_extraOptions); } /** * @dev Internal function to assert that options are of type 3. * @param _options The options to be checked. */ function _assertOptionsType3(bytes memory _options) internal pure virtual { uint16 optionsType; assembly { optionsType := mload(add(_options, 2)) } if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IMessageLibManager } from "./IMessageLibManager.sol"; import { IMessagingComposer } from "./IMessagingComposer.sol"; import { IMessagingChannel } from "./IMessagingChannel.sol"; import { IMessagingContext } from "./IMessagingContext.sol"; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { Origin } from "./ILayerZeroEndpointV2.sol"; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.1) (governance/Governor.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721Receiver.sol"; import "../token/ERC1155/IERC1155Receiver.sol"; import "../utils/cryptography/ECDSA.sol"; import "../utils/cryptography/EIP712.sol"; import "../utils/introspection/ERC165.sol"; import "../utils/math/SafeCast.sol"; import "../utils/structs/DoubleEndedQueue.sol"; import "../utils/Address.sol"; import "../utils/Context.sol"; import "./IGovernor.sol"; /** * @dev Core of the governance system, designed to be extended though various modules. * * This contract is abstract and requires several functions to be implemented in various modules: * * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} * - A voting module must implement {_getVotes} * - Additionally, {votingPeriod} must also be implemented * * _Available since v4.3._ */ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); // solhint-disable var-name-mixedcase struct ProposalCore { // --- start retyped from Timers.BlockNumber at offset 0x00 --- uint64 voteStart; address proposer; bytes4 __gap_unused0; // --- start retyped from Timers.BlockNumber at offset 0x20 --- uint64 voteEnd; bytes24 __gap_unused1; // --- Remaining fields starting at offset 0x40 --------------- bool executed; bool canceled; } // solhint-enable var-name-mixedcase string private _name; /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore) mapping(uint256 => ProposalCore) private _proposals; // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. DoubleEndedQueue.Bytes32Deque private _governanceCall; /** * @dev Restricts a function so it can only be executed through governance proposals. For example, governance * parameter setters in {GovernorSettings} are protected using this modifier. * * The governance executing address may be different from the Governor's own address, for example it could be a * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, * for example, additional timelock proposers are not able to change governance parameters without going through the * governance protocol (since v4.6). */ modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) {} } _; } /** * @dev Sets the value for {name} and {version} */ constructor(string memory name_) EIP712(name_, version()) { _name = name_; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { require(_executor() == address(this), "Governor: must send to executor"); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector; bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector; // The original interface id in v4.3. bytes4 governor43Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId ^ governorParamsId; // An updated interface id in v4.6, with params added. bytes4 governor46Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId; // For the updated interface id in v4.9, we use governorCancelId directly. return interfaceId == governor43Id || interfaceId == governor46Id || interfaceId == governorCancelId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IGovernor-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IGovernor-version}. */ function version() public view virtual override returns (string memory) { return "1"; } /** * @dev See {IGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in * advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual override returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } /** * @dev See {IGovernor-state}. */ function state(uint256 proposalId) public view virtual override returns (ProposalState) { ProposalCore storage proposal = _proposals[proposalId]; if (proposal.executed) { return ProposalState.Executed; } if (proposal.canceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { return ProposalState.Succeeded; } else { return ProposalState.Defeated; } } /** * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev See {IGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteStart; } /** * @dev See {IGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteEnd; } /** * @dev Returns the account that created a given proposal. */ function proposalProposer(uint256 proposalId) public view virtual override returns (address) { return _proposals[proposalId].proposer; } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`. */ function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params ) internal virtual; /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual override returns (uint256) { address proposer = _msgSender(); require(_isValidDescriptionForProposer(proposer, description), "Governor: proposer restricted"); uint256 currentTimepoint = clock(); require( getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold" ); uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); require(_proposals[proposalId].voteStart == 0, "Governor: proposal already exists"); uint256 snapshot = currentTimepoint + votingDelay(); uint256 deadline = snapshot + votingPeriod(); _proposals[proposalId] = ProposalCore({ proposer: proposer, voteStart: SafeCast.toUint64(snapshot), voteEnd: SafeCast.toUint64(deadline), executed: false, canceled: false, __gap_unused0: 0, __gap_unused1: 0 }); emit ProposalCreated( proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description ); return proposalId; } /** * @dev See {IGovernor-execute}. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require( currentState == ProposalState.Succeeded || currentState == ProposalState.Queued, "Governor: proposal not successful" ); _proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); return proposalId; } /** * @dev See {IGovernor-cancel}. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel"); require(_msgSender() == _proposals[proposalId].proposer, "Governor: only proposer can cancel"); return _cancel(targets, values, calldatas, descriptionHash); } /** * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism */ function _execute( uint256 /* proposalId */, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { string memory errorMessage = "Governor: call reverted without message"; for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); Address.verifyCallResult(success, returndata, errorMessage); } } /** * @dev Hook before execution is triggered. */ function _beforeExecute( uint256 /* proposalId */, address[] memory targets, uint256[] memory /* values */, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { for (uint256 i = 0; i < targets.length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } } /** * @dev Hook after execution is triggered. */ function _afterExecute( uint256 /* proposalId */, address[] memory /* targets */, uint256[] memory /* values */, bytes[] memory /* calldatas */, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { if (!_governanceCall.empty()) { _governanceCall.clear(); } } } /** * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * canceled to allow distinguishing it from executed proposals. * * Emits a {IGovernor-ProposalCanceled} event. */ function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require( currentState != ProposalState.Canceled && currentState != ProposalState.Expired && currentState != ProposalState.Executed, "Governor: proposal not active" ); _proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IGovernor-getVotes}. */ function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { return _getVotes(account, timepoint, _defaultParams()); } /** * @dev See {IGovernor-getVotesWithParams}. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) public view virtual override returns (uint256) { return _getVotes(account, timepoint, params); } /** * @dev See {IGovernor-castVote}. */ function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReason}. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } /** * @dev See {IGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } /** * @dev See {IGovernor-castVoteBySig}. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s ); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params) ) ) ), v, r, s ); return _castVote(proposalId, voter, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason ) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params ) internal virtual returns (uint256) { ProposalCore storage proposal = _proposals[proposalId]; require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart, params); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { emit VoteCast(account, proposalId, support, weight, reason); } else { emit VoteCastWithParams(account, proposalId, support, weight, reason, params); } return weight; } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{value: value}(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. */ function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. */ function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } /** * @dev Check if the proposer is authorized to submit a proposal with the given description. * * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string * (case insensitive), then the submission of this proposal will only be authorized to said address. * * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure * that no other address can submit the same proposal. An attacker would have to either remove or change that part, * which would result in a different proposal id. * * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes: * - If the `0x???` part is not a valid hex string. * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits. * - If it ends with the expected suffix followed by newlines or other whitespace. * - If it ends with some other similar suffix, e.g. `#other=abc`. * - If it does not end with any such suffix. */ function _isValidDescriptionForProposer( address proposer, string memory description ) internal view virtual returns (bool) { uint256 len = bytes(description).length; // Length is too short to contain a valid proposer suffix if (len < 52) { return true; } // Extract what would be the `#proposer=0x` marker beginning the suffix bytes12 marker; assembly { // - Start of the string contents in memory = description + 32 // - First character of the marker = len - 52 // - Length of "#proposer=0x0000000000000000000000000000000000000000" = 52 // - We read the memory word starting at the first character of the marker: // - (description + 32) + (len - 52) = description + (len - 20) // - Note: Solidity will ignore anything past the first 12 bytes marker := mload(add(description, sub(len, 20))) } // If the marker is not found, there is no proposer suffix to check if (marker != bytes12("#proposer=0x")) { return true; } // Parse the 40 characters following the marker as uint160 uint160 recovered = 0; for (uint256 i = len - 40; i < len; ++i) { (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]); // If any of the characters is not a hex digit, ignore the suffix entirely if (!isHex) { return true; } recovered = (recovered << 4) | value; } return recovered == uint160(proposer); } /** * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16` */ function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) { uint8 c = uint8(char); unchecked { // Case 0-9 if (47 < c && c < 58) { return (true, c - 48); } // Case A-F else if (64 < c && c < 71) { return (true, c - 55); } // Case a-f else if (96 < c && c < 103) { return (true, c - 87); } // Else: not a hex char else { return (false, 0); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol) pragma solidity ^0.8.0; import "../interfaces/IERC165.sol"; import "../interfaces/IERC6372.sol"; /** * @dev Interface of the {Governor} core. * * _Available since v4.3._ */ abstract contract IGovernor is IERC165, IERC6372 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description ); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the ERC712 domain separator). */ function name() public view virtual returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" */ function version() public view virtual returns (string memory); /** * @notice module:core * @dev See {IERC6372} */ function clock() public view virtual override returns (uint48); /** * @notice module:core * @dev See EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public view virtual returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) public view virtual returns (ProposalState); /** * @notice module:core * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the * following block. */ function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is * possible to cast a vote during this block. */ function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev The account that created a proposal. */ function proposalProposer(uint256 proposalId) public view virtual returns (address); /** * @notice module:user-config * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends * on the clock (see EIP-6372) this contract uses. * * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a * proposal starts. */ function votingDelay() public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock * (see EIP-6372) this contract uses. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. */ function votingPeriod() public view virtual returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}). */ function quorum(uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) public view virtual returns (uint256); /** * @notice module:voting * @dev Returns whether `account` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); /** * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a * duration specified by {IGovernor-votingPeriod}. * * Emits a {ProposalCreated} event. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. * * Emits a {ProposalExecuted} event. * * Note: some module can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual returns (uint256 proposalId); /** * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. * before the vote starts. * * Emits a {ProposalCanceled} event. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256 proposalId); /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual returns (uint256 balance); /** * @dev Cast a vote using the user's cryptographic signature. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorCountingSimple.sol) pragma solidity ^0.8.0; import "../Governor.sol"; /** * @dev Extension of {Governor} for simple, 3 options, vote counting. * * _Available since v4.3._ */ abstract contract GovernorCountingSimple is Governor { /** * @dev Supported vote types. Matches Governor Bravo ordering. */ enum VoteType { Against, For, Abstain } struct ProposalVote { uint256 againstVotes; uint256 forVotes; uint256 abstainVotes; mapping(address => bool) hasVoted; } mapping(uint256 => ProposalVote) private _proposalVotes; /** * @dev See {IGovernor-COUNTING_MODE}. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual override returns (string memory) { return "support=bravo&quorum=for,abstain"; } /** * @dev See {IGovernor-hasVoted}. */ function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { return _proposalVotes[proposalId].hasVoted[account]; } /** * @dev Accessor to the internal vote counts. */ function proposalVotes( uint256 proposalId ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } /** * @dev See {Governor-_quorumReached}. */ function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes; } /** * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. */ function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return proposalVote.forVotes > proposalVote.againstVotes; } /** * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo). */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory // params ) internal virtual override { ProposalVote storage proposalVote = _proposalVotes[proposalId]; require(!proposalVote.hasVoted[account], "GovernorVotingSimple: vote already cast"); proposalVote.hasVoted[account] = true; if (support == uint8(VoteType.Against)) { proposalVote.againstVotes += weight; } else if (support == uint8(VoteType.For)) { proposalVote.forVotes += weight; } else if (support == uint8(VoteType.Abstain)) { proposalVote.abstainVotes += weight; } else { revert("GovernorVotingSimple: invalid value for enum VoteType"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.0; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; import "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSA.sol"; import "../ShortStrings.sol"; import "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. 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); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol) pragma solidity ^0.8.4; import "../math/SafeCast.sol"; /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ```solidity * DoubleEndedQueue.Bytes32Deque queue; * ``` * * _Available since v4.6._ */ library DoubleEndedQueue { /** * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. */ error Empty(); /** * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. */ error OutOfBounds(); /** * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at * data[end - 1]. */ struct Bytes32Deque { int128 _begin; int128 _end; mapping(int128 => bytes32) _data; } /** * @dev Inserts an item at the end of the queue. */ function pushBack(Bytes32Deque storage deque, bytes32 value) internal { int128 backIndex = deque._end; deque._data[backIndex] = value; unchecked { deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } /** * @dev Inserts an item at the beginning of the queue. */ function pushFront(Bytes32Deque storage deque, bytes32 value) internal { int128 frontIndex; unchecked { frontIndex = deque._begin - 1; } deque._data[frontIndex] = value; deque._begin = frontIndex; } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; value = deque._data[frontIndex]; delete deque._data[frontIndex]; unchecked { deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with `Empty` if the queue is empty. */ function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; return deque._data[frontIndex]; } /** * @dev Returns the item at the end of the queue. * * Reverts with `Empty` if the queue is empty. */ function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } return deque._data[backIndex]; } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with `OutOfBounds` if the index is out of bounds. */ function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { // int256(deque._begin) is a safe upcast int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index)); if (idx >= deque._end) revert OutOfBounds(); return deque._data[idx]; } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Bytes32Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Bytes32Deque storage deque) internal view returns (uint256) { // The interface preserves the invariant that begin <= end so we assume this will not overflow. // We also assume there are at most int256.max items in the queue. unchecked { return uint256(int256(deque._end) - int256(deque._begin)); } } /** * @dev Returns true if the queue is empty. */ function empty(Bytes32Deque storage deque) internal view returns (bool) { return deque._end <= deque._begin; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IVoteSendSide } from "./finalizer/interfaces/IFinalizer.sol"; /** * @title LzFeeSwitchGovernorBase * @dev Abstract base contract for managing the fee switch governor functionality. */ abstract contract LzFeeSwitchGovernorBase is Ownable, IVoteSendSide { // =============================== Errors =============================== /// @dev Error for invalid voting proposal. error ErrInvalidVotingProposal(); /// @dev Error for out of voting period. error ErrOutOfVotingPeriod(); /// @dev Error for unauthorized proposer access. error ErrNotProposer(); /// @dev Error for unsupported operation. error ErrNotSupported(); /// @dev Error for unauthorized vote access. error ErrNotVote(); // =============================== Variables =============================== /// @dev Address of the vote contract. address public immutable voteAddress; /// @dev Address of the proposer. address public proposer; /// @dev Mapping to track inflight votes by proposal ID. mapping(uint256 proposalId => uint256) public castVoteSentCount; /// @dev Mapping to track if a voter has sent a vote. mapping(uint256 proposalId => mapping(address => bool)) public hasSentVote; // =============================== Modifiers =============================== /** * @dev Modifier to restrict access to only the vote contract. */ modifier onlyVote() { if (_msgSender() != voteAddress) revert ErrNotVote(); _; } /** * @dev Modifier to restrict access to only the proposer. */ modifier onlyProposer() { if (_msgSender() != proposer) revert ErrNotProposer(); _; } /** * @dev Constructor to initialize the vote contract address and set the proposer. * @param _vote The address of the vote contract. */ constructor(address _vote) { voteAddress = _vote; proposer = _msgSender(); } // =============================== Setters/Getters =============================== /** * @notice Sets the proposer address. * @dev Only the owner can call this function. * @param _newProposer The address of the new proposer. */ function setProposer(address _newProposer) external onlyOwner { proposer = _newProposer; } // =============================== Virtual =============================== /** * @notice Returns the current clock time. * @return The current clock time as a uint48. */ function clock() public view virtual returns (uint48); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IVoteSendSide * @dev Interface for the vote sending side of the finalizer contract. */ interface IVoteSendSide { /** * @notice Gets the count of votes sent for a given proposal. * @param _proposalId The ID of the proposal. * @return The count of votes sent. */ function castVoteSentCount(uint256 _proposalId) external view returns (uint256); } /** * @title IFinalizer * @dev Interface for the finalizer contract. */ interface IFinalizer { /** * @notice Quotes the fee required to finalize a proposal. * @param _proposalId The ID of the proposal. * @param _options The options for the read operation. * @param _payInLzToken A boolean indicating whether to pay in LzToken. * @return The calculated messaging fee. */ function quote( uint256 _proposalId, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); /** * @notice Finalizes a proposal by sending a read request to multiple chains. * @param _proposalId The ID of the proposal. * @param _options The options for the read operation. * @param _lzTokenFee The fee to be paid in LzToken. * @param _refundAddress The address to refund any excess fee. * @return The messaging receipt. */ function finalize( uint256 _proposalId, bytes calldata _options, uint256 _lzTokenFee, address _refundAddress ) external payable returns (MessagingReceipt memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; interface IVoteMessaging { struct Ballot { bytes32 voter; // using bytes32 to be compatible with VMs with 32 bytes address size uint votingPower; bool enabledFeeSwitch; uint256 timeStamp; } // msg.value will be passed along to the receiver contract function sendBallot(Ballot memory _ballot) external payable; // the fee is agnostic to the params function quoteSendBallot() external view returns (MessagingFee memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { MessagingFee } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; interface IVotePower { // msg.value will be passed along to the receiver contract function vote(address _user, bool _enabledFeeSwitch) external payable; // the fee is agnostic to the params function quoteVote() external view returns (MessagingFee memory); }
// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 2000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"uint32","name":"_mainEid","type":"uint32"},{"internalType":"address","name":"_vote","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrInvalidVotingProposal","type":"error"},{"inputs":[],"name":"ErrNotProposer","type":"error"},{"inputs":[],"name":"ErrNotSupported","type":"error"},{"inputs":[],"name":"ErrNotVote","type":"error"},{"inputs":[],"name":"ErrOutOfVotingPeriod","type":"error"},{"inputs":[{"internalType":"uint256","name":"provided","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InsufficientMessagingFee","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint256","name":"provided","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"NativeFeeNotMatch","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"ReadRequestInProgress","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"LzVoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"castVoteSentCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeMultiplierBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"hasSentVote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint64","name":"snapshot","type":"uint64"}],"internalType":"struct VoteParam","name":"","type":"tuple"},{"components":[{"internalType":"bytes","name":"readOptions","type":"bytes"},{"internalType":"bytes","name":"messagingOptions","type":"bytes"}],"internalType":"struct OptionsParam","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"readNativeFee","type":"uint256"},{"internalType":"uint256","name":"readLzTokenFee","type":"uint256"},{"internalType":"uint256","name":"messagingNativeFee","type":"uint256"}],"internalType":"struct VoteFee","name":"","type":"tuple"}],"name":"lzCastVote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mainEid","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"},{"internalType":"uint64","name":"_snapshot","type":"uint64"},{"internalType":"uint256","name":"_votes","type":"uint256"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"onVotesReceived","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint64","name":"snapshot","type":"uint64"}],"internalType":"struct VoteParam","name":"","type":"tuple"},{"components":[{"internalType":"bytes","name":"readOptions","type":"bytes"},{"internalType":"bytes","name":"messagingOptions","type":"bytes"}],"internalType":"struct OptionsParam","name":"","type":"tuple"},{"internalType":"bool","name":"","type":"bool"}],"name":"quoteCastVote","outputs":[{"components":[{"internalType":"uint256","name":"readNativeFee","type":"uint256"},{"internalType":"uint256","name":"readLzTokenFee","type":"uint256"},{"internalType":"uint256","name":"messagingNativeFee","type":"uint256"}],"internalType":"struct VoteFee","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteSendBallot","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteVote","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"voter","type":"bytes32"},{"internalType":"uint256","name":"votingPower","type":"uint256"},{"internalType":"bool","name":"enabledFeeSwitch","type":"bool"},{"internalType":"uint256","name":"timeStamp","type":"uint256"}],"internalType":"struct IVoteMessaging.Ballot","name":"","type":"tuple"}],"name":"sendBallot","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_bps","type":"uint16"}],"name":"setFeeMultiplierBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newProposer","type":"address"}],"name":"setProposer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_votesReaderContract","type":"address"}],"name":"setVotesReader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint64","name":"snapshot","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"}],"internalType":"struct LzFeeSwitchGovernorSide.Proposal","name":"_proposal","type":"tuple"}],"name":"setVotingProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_voter","type":"address"},{"internalType":"bool","name":"_enabledFeeSwitch","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"voteAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votesReader","outputs":[{"internalType":"contract IVotesReader","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingProposal","outputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint64","name":"snapshot","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040516200388f3803806200388f833981016040819052620000349162000176565b8233838282818187620000478262000109565b6001600160a01b03908116608052600180546001600160a01b0319163317905582811660a05281166200008d57604051632d618d8160e21b815260040160405180910390fd5b60a05160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b158015620000d557600080fd5b505af1158015620000ea573d6000803e3d6000fd5b50505063ffffffff90951660c05250620001ca98505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200017157600080fd5b919050565b6000806000606084860312156200018c57600080fd5b620001978462000159565b9250602084015163ffffffff81168114620001b157600080fd5b9150620001c16040850162000159565b90509250925092565b60805160a05160c0516136416200024e600039600081816105d30152818161152c0152818161177a015281816119de01528181611ab801528181611c710152611ca00152600081816103d801528181610eca01528181611c3201528181611efc01528181611f8e01526120e00152600081816102cf0152610cd901526136416000f3fe6080604052600436106101e75760003560e01c80638da5cb5b11610102578063bb0b6a5311610095578063e3fbc36311610064578063e3fbc363146106aa578063ef264939146106b8578063f2fde38b146106da578063f3562c26146106fa57600080fd5b8063bb0b6a531461062a578063bc70b35414610657578063bd041c4d14610677578063ca5eb5e11461068a57600080fd5b8063a7b3ece4116100d1578063a7b3ece414610556578063a8e4fb90146105a1578063b67d5433146105c1578063b98bd0701461060a57600080fd5b80638da5cb5b146104aa57806391ddadf4146104c857806391ffc9b2146104f4578063a3ae02571461051457600080fd5b80635535d4611161017a5780635e9c67d8116101495780635e9c67d8146103fa5780636a302b771461041a578063715018a614610475578063872e411d1461048a57600080fd5b80635535d4611461035857806355651b0e14610378578063597cbd12146103985780635e280f11146103c657600080fd5b8063376cc2e1116101b6578063376cc2e11461026f5780633bd67dca146102aa5780633d6dc928146102bd5780634bf5d7e91461030957600080fd5b80630604d7dd146101f357806317442b70146102085780631fb4a2281461022f5780633400288b1461024f57600080fd5b366101ee57005b600080fd5b6102066102013660046126af565b61070f565b005b34801561021457600080fd5b50604080516001815260006020820152015b60405180910390f35b34801561023b57600080fd5b5061020661024a366004612732565b610741565b34801561025b57600080fd5b5061020661026a36600461276f565b610778565b34801561027b57600080fd5b5061029c61028a366004612799565b60026020526000908152604090205481565b604051908152602001610226565b6102066102b8366004612811565b61078e565b3480156102c957600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610226565b34801561031557600080fd5b5060408051808201909152601b81527f6d6f64653d74696d657374616d702666726f6d3d64656661756c74000000000060208201525b60405161022691906128d4565b34801561036457600080fd5b5061034b6103733660046128f9565b610804565b34801561038457600080fd5b5061020661039336600461292c565b6108a9565b3480156103a457600080fd5b506008546103b39061ffff1681565b60405161ffff9091168152602001610226565b3480156103d257600080fd5b506102f17f000000000000000000000000000000000000000000000000000000000000000081565b34801561040657600080fd5b506005546102f1906001600160a01b031681565b34801561042657600080fd5b50600954600a5461044f919067ffffffffffffffff808216916801000000000000000090041683565b6040805193845267ffffffffffffffff9283166020850152911690820152606001610226565b34801561048157600080fd5b50610206610953565b34801561049657600080fd5b506102066104a5366004612977565b610967565b3480156104b657600080fd5b506000546001600160a01b03166102f1565b3480156104d457600080fd5b506104dd6109a4565b60405165ffffffffffff9091168152602001610226565b34801561050057600080fd5b5061020661050f366004612732565b6109b3565b34801561052057600080fd5b5061053461052f3660046129bc565b610a24565b6040805182518152602080840151908201529181015190820152606001610226565b34801561056257600080fd5b50610591610571366004612a45565b600360209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610226565b3480156105ad57600080fd5b506001546102f1906001600160a01b031681565b3480156105cd57600080fd5b506105f57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610226565b34801561061657600080fd5b50610206610625366004612a75565b610a48565b34801561063657600080fd5b5061029c610645366004612aea565b60046020526000908152604090205481565b34801561066357600080fd5b5061034b610672366004612b05565b610a62565b610206610685366004612b66565b610c1b565b34801561069657600080fd5b506102066106a5366004612732565b610e8a565b610206610201366004612b94565b3480156106c457600080fd5b506106cd610f22565b6040516102269190612c14565b3480156106e657600080fd5b506102066106f5366004612732565b6110bc565b34801561070657600080fd5b506106cd61114c565b6040517fa3ce824a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107496111dc565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6107806111dc565b61078a8282611236565b5050565b6005546001600160a01b0316336001600160a01b0316146107db576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680549060006107eb83612c41565b91905055506107fd858585858561128b565b5050505050565b60076020908152600092835260408084209091529082529020805461082890612c58565b80601f016020809104026020016040519081016040528092919081815260200182805461085490612c58565b80156108a15780601f10610876576101008083540402835291602001916108a1565b820191906000526020600020905b81548152906001019060200180831161088457829003601f168201915b505050505081565b6001546001600160a01b0316336001600160a01b0316146108f6576040517f5b0f85e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516009556020810151600a805460409093015167ffffffffffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909416921691909117919091179055565b61095b6111dc565b6109656000611352565b565b61096f6111dc565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff92909216919091179055565b60006109ae6113af565b905090565b6109bb6111dc565b600654156109f5576040517feebae33000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b61070f60405180606001604052806000815260200160008152602001600081525090565b610a506111dc565b61078a610a5d8284612cb4565b6113ba565b63ffffffff8416600090815260076020908152604080832061ffff87168452909152812080546060929190610a9690612c58565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac290612c58565b8015610b0f5780601f10610ae457610100808354040283529160200191610b0f565b820191906000526020600020905b815481529060010190602001808311610af257829003601f168201915b505050505090508051600003610b5f5783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450610c139350505050565b6000839003610b6f579050610c13565b60028310610bed57610bb684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114cc92505050565b80610bc48460028188612dca565b604051602001610bd693929190612df4565b604051602081830303815290604052915050610c13565b8383604051639a6d49cd60e01b8152600401610c0a929190612e1c565b60405180910390fd5b949350505050565b600954600003610c57576040517fc748fea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610c616109a4565b600a5465ffffffffffff91909116915067ffffffffffffffff16811080610c9f5750600a5468010000000000000000900467ffffffffffffffff1681115b15610cd6576040517fd80bf02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610d38576040517f46e52c4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182526009548152600a5467ffffffffffffffff8082166020840152680100000000000000009091041691810191909152600083610d7e576000610d81565b60015b6040805160a08101825260ff83168152815160208181018452600080835281840192909252835180820185528281528385015286516060808501919091528782015167ffffffffffffffff16608085015284518082018652808601848152815285518084018752848152818401528551918201865234825291810183905293840191909152929350610e149288926114f8565b81516000908152600260205260408120805491610e3083612e61565b9091555050905160009081526003602090815260408083206001600160a01b0390971683529590529390932080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050565b610e926111dc565b6040517fca5eb5e10000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b158015610f0e57600080fd5b505af11580156107fd573d6000803e3d6000fd5b6040805180820190915260008082526020820152600954600003610f72576040517fc748fea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f7c6109a4565b600a5465ffffffffffff91909116915067ffffffffffffffff16811080610fba5750600a5468010000000000000000900467ffffffffffffffff1681115b15610ff1576040517fd80bf02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061108760006040518060a001604052806001600281111561101657611016612e4b565b60ff16815260408051602081810183526000808352818501929092528251808201845282815283850152600954606080860191909152600a5467ffffffffffffffff16608090950194909452825193840183528383018281528452825180820190935281835283019190915261173d565b90506040518060400160405280826040015183600001516110a89190612e7b565b815260200182602001518152509250505090565b6110c46111dc565b6001600160a01b0381166111405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c0a565b61114981611352565b50565b60408051808201909152600080825260208201526109ae60006040518060a001604052806001600281111561118357611183612e4b565b60ff168152604080516020818101835260008083528185019290925282518082018452828152838501526009546060850152600a5467ffffffffffffffff1660809094019390935281519283019091528082529061193c565b6000546001600160a01b031633146109655760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c0a565b63ffffffff8216600081815260046020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b60008060008060006112d287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b2192505050565b945094509450945094506113456040518061010001604052808c6001600160a01b031681526020018767ffffffffffffffff1681526020018681526020018581526020018a8152602001848152602001348461132e9190612e7b565b81526020018c6001600160a01b0316815250611b8d565b5050505050505050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006109ae42611dd3565b60005b8151811015611491576113ec8282815181106113db576113db612e8e565b6020026020010151604001516114cc565b8181815181106113fe576113fe612e8e565b6020026020010151604001516007600084848151811061142057611420612e8e565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061145a5761145a612e8e565b60200260200101516020015161ffff1661ffff16815260200190815260200160002090816114889190612ef4565b506001016113bd565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516114c19190612fb4565b60405180910390a150565b600281015161ffff811660031461078a5781604051639a6d49cd60e01b8152600401610c0a91906128d4565b61150484848484611e55565b90506115138160200151611ef2565b60006116156115206109a4565b606086015163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166000908152600760209081526040808320600184529091529020805465ffffffffffff9390931692889161160b9161158390612c58565b80601f01602080910402602001604051908101604052809291908181526020018280546115af90612c58565b80156115fc5780601f106115d1576101008083540402835291602001916115fc565b820191906000526020600020905b8154815290600101906020018083116115df57829003601f168201915b50505050508860200151611fb3565b866040015161206c565b600554835160808701518651604080518082018252885181526020808a01519082015290517fdd3acfcd0000000000000000000000000000000000000000000000000000000081529596506001600160a01b039094169463dd3acfcd94611687938c939092899290859060040161303f565b60806040518083038185885af11580156116a5573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116ca919061310c565b50600680549060006116db83612e61565b91905055508360600151856001600160a01b03167fc1bef9e33878816461aa6c2b21411bb2993d2d127ed1212fa50351e123c3061486600001518760200151886040015160405161172e9392919061314a565b60405180910390a35050505050565b61176160405180606001604052806000815260200160008152602001600081525090565b600061186061176e6109a4565b606087015163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166000908152600760209081526040808320600184529091529020805465ffffffffffff93909316928991611859916117d190612c58565b80601f01602080910402602001604051908101604052809291908181526020018280546117fd90612c58565b801561184a5780601f1061181f5761010080835404028352916020019161184a565b820191906000526020600020905b81548152906001019060200180831161182d57829003601f168201915b50505050508960200151611fb3565b600061206c565b600554608087015186516040517f77b2a5650000000000000000000000000000000000000000000000000000000081529394506000936001600160a01b03909316926377b2a565926118bb928c928891908b90600401613182565b6040805180830381865afa1580156118d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fb91906131db565b9050600061191088886000896020015161193c565b604080516060810182528451815260209485015194810194909452905190830152509695505050505050565b604080518082019091526000808252602082015260006119d760405180610100016040528087606001518152602001886001600160a01b031681526020016119826109a4565b65ffffffffffff1667ffffffffffffffff168152602001876000015160ff1681526020018760200151815260200187604001518152602001876080015167ffffffffffffffff168152602001868152506120a1565b63ffffffff7f000000000000000000000000000000000000000000000000000000000000000016600090815260076020908152604080832060018452909152812080549293509091611ab19190611a2d90612c58565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5990612c58565b8015611aa65780601f10611a7b57610100808354040283529160200191611aa6565b820191906000526020600020905b815481529060010190602001808311611a8957829003601f168201915b505050505085611fb3565b9050611ae07f0000000000000000000000000000000000000000000000000000000000000000838360006120ca565b600854815191945061271091611afa9161ffff16906131f7565b611b04919061320e565b83518490611b13908390612e7b565b905250919695505050505050565b600080611b636040518060a00160405280600060ff168152602001606081526020016060815260200160008152602001600067ffffffffffffffff1681525090565b6060600085806020019051810190611b7b9190613275565b939a9299509097509550909350915050565b611b956125c6565b6000611c296040518061010001604052808560400151815260200185600001516001600160a01b03168152602001856020015167ffffffffffffffff16815260200185606001516000015160ff1681526020018560600151602001518152602001856060015160400151815260200185606001516080015167ffffffffffffffff16815260200185608001518152506120a1565b905060004790507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a4508560c001516040518060a001604052807f000000000000000000000000000000000000000000000000000000000000000063ffffffff168152602001611cc47f00000000000000000000000000000000000000000000000000000000000000006121ab565b81526020018681526020018860a00151815260200160001515815250306040518463ffffffff1660e01b8152600401611cfe929190613387565b60806040518083038185885af1158015611d1c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611d41919061310c565b92506000818560c0015147611d569190612e7b565b611d609190613400565b90508015611dcb5760e08501516040516000916001600160a01b03169083156108fc0290849084818181858888f19350505050905080611dc957604051329083156108fc029084906000818181858888f19350505050158015611dc7573d6000803e3d6000fd5b505b505b505050919050565b600065ffffffffffff821115611e515760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201527f38206269747300000000000000000000000000000000000000000000000000006064820152608401610c0a565b5090565b611e7960405180606001604052806000815260200160008152602001600081525090565b6000611e8c86866000876020015161193c565b8051909150341015611ed65780516040517fa49e79ba0000000000000000000000000000000000000000000000000000000081523460048201526024810191909152604401610c0a565b8051611ee29034613400565b8252516040820152949350505050565b80156111495760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7c9190613413565b905061078a6001600160a01b038216337f000000000000000000000000000000000000000000000000000000000000000085612200565b60608251600003611fc5575080612066565b8151600003611fd5575081612066565b600283511080611fe6575060028251105b15612016576002835110611ffa5781611ffc565b825b604051639a6d49cd60e01b8152600401610c0a91906128d4565b61201f836114cc565b612028826114cc565b82612043600280855161203b9190613400565b85919061228e565b604051602001612054929190613430565b60405160208183030381529060405290505b92915050565b6060858585858560405160200161208795949392919061345f565b604051602081830303815290604052905095945050505050565b6060816040516020016120b4919061351c565b6040516020818303038152906040529050919050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161212d896121ab565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612162929190613387565b6040805180830381865afa15801561217e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a291906131db565b95945050505050565b63ffffffff811660009081526004602052604081205480612066576040517ff6ff4fb700000000000000000000000000000000000000000000000000000000815263ffffffff84166004820152602401610c0a565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526122889085906123b6565b50505050565b60608161229c81601f612e7b565b10156122ea5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610c0a565b6122f48284612e7b565b845110156123445760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610c0a565b60608215801561236357604051915060008252602082016040526123ad565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561239c578051835260209283019201612384565b5050858452601f01601f1916604052505b50949350505050565b600061240b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124a39092919063ffffffff16565b905080516000148061242c57508080602001905181019061242c91906135d2565b61249e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c0a565b505050565b6060610c13848460008585600080866001600160a01b031685876040516124ca91906135ef565b60006040518083038185875af1925050503d8060008114612507576040519150601f19603f3d011682016040523d82523d6000602084013e61250c565b606091505b509150915061251d87838387612528565b979650505050505050565b60608315612597578251600003612590576001600160a01b0385163b6125905760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c0a565b5081610c13565b610c1383838151156125ac5781518083602001fd5b8060405162461bcd60e51b8152600401610c0a91906128d4565b604051806060016040528060008019168152602001600067ffffffffffffffff168152602001612609604051806040016040528060008152602001600081525090565b905290565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156126475761264761260e565b60405290565b60405160a0810167ffffffffffffffff811182821017156126475761264761260e565b604051601f8201601f1916810167ffffffffffffffff811182821017156126995761269961260e565b604052919050565b801515811461114957600080fd5b6000608082840312156126c157600080fd5b6040516080810181811067ffffffffffffffff821117156126e4576126e461260e565b806040525082358152602083013560208201526040830135612705816126a1565b60408201526060928301359281019290925250919050565b6001600160a01b038116811461114957600080fd5b60006020828403121561274457600080fd5b813561274f8161271d565b9392505050565b803563ffffffff8116811461276a57600080fd5b919050565b6000806040838503121561278257600080fd5b61278b83612756565b946020939093013593505050565b6000602082840312156127ab57600080fd5b5035919050565b67ffffffffffffffff8116811461114957600080fd5b60008083601f8401126127da57600080fd5b50813567ffffffffffffffff8111156127f257600080fd5b60208301915083602082850101111561280a57600080fd5b9250929050565b60008060008060006080868803121561282957600080fd5b85356128348161271d565b94506020860135612844816127b2565b935060408601359250606086013567ffffffffffffffff81111561286757600080fd5b612873888289016127c8565b969995985093965092949392505050565b60005b8381101561289f578181015183820152602001612887565b50506000910152565b600081518084526128c0816020860160208601612884565b601f01601f19169290920160200192915050565b60208152600061274f60208301846128a8565b803561ffff8116811461276a57600080fd5b6000806040838503121561290c57600080fd5b61291583612756565b9150612923602084016128e7565b90509250929050565b60006060828403121561293e57600080fd5b612946612624565b823581526020830135612958816127b2565b6020820152604083013561296b816127b2565b60408201529392505050565b60006020828403121561298957600080fd5b61274f826128e7565b600060a082840312156129a457600080fd5b50919050565b6000604082840312156129a457600080fd5b600080600080608085870312156129d257600080fd5b84356129dd8161271d565b9350602085013567ffffffffffffffff808211156129fa57600080fd5b612a0688838901612992565b94506040870135915080821115612a1c57600080fd5b50612a29878288016129aa565b9250506060850135612a3a816126a1565b939692955090935050565b60008060408385031215612a5857600080fd5b823591506020830135612a6a8161271d565b809150509250929050565b60008060208385031215612a8857600080fd5b823567ffffffffffffffff80821115612aa057600080fd5b818501915085601f830112612ab457600080fd5b813581811115612ac357600080fd5b8660208260051b8501011115612ad857600080fd5b60209290920196919550909350505050565b600060208284031215612afc57600080fd5b61274f82612756565b60008060008060608587031215612b1b57600080fd5b612b2485612756565b9350612b32602086016128e7565b9250604085013567ffffffffffffffff811115612b4e57600080fd5b612b5a878288016127c8565b95989497509550505050565b60008060408385031215612b7957600080fd5b8235612b848161271d565b91506020830135612a6a816126a1565b600080600083850360a0811215612baa57600080fd5b843567ffffffffffffffff80821115612bc257600080fd5b612bce88838901612992565b95506020870135915080821115612be457600080fd5b50612bf1878288016129aa565b9350506060603f1982011215612c0657600080fd5b506040840190509250925092565b815181526020808301519082015260408101612066565b634e487b7160e01b600052601160045260246000fd5b600081612c5057612c50612c2b565b506000190190565b600181811c90821680612c6c57607f821691505b6020821081036129a457634e487b7160e01b600052602260045260246000fd5b600067ffffffffffffffff821115612ca657612ca661260e565b50601f01601f191660200190565b600067ffffffffffffffff80841115612ccf57612ccf61260e565b8360051b6020612ce0818301612670565b868152918501918181019036841115612cf857600080fd5b865b84811015612dbe57803586811115612d125760008081fd5b88016060368290031215612d265760008081fd5b612d2e612624565b612d3782612756565b8152612d448683016128e7565b8682015260408083013589811115612d5c5760008081fd5b929092019136601f840112612d715760008081fd5b8235612d84612d7f82612c8c565b612670565b8181523689838701011115612d995760008081fd5b818986018a830137600091810189019190915290820152845250918301918301612cfa565b50979650505050505050565b60008085851115612dda57600080fd5b83861115612de757600080fd5b5050820193919092039150565b60008451612e06818460208901612884565b8201838582376000930192835250909392505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052602160045260246000fd5b60006000198203612e7457612e74612c2b565b5060010190565b8082018082111561206657612066612c2b565b634e487b7160e01b600052603260045260246000fd5b601f82111561249e576000816000526020600020601f850160051c81016020861015612ecd5750805b601f850160051c820191505b81811015612eec57828155600101612ed9565b505050505050565b815167ffffffffffffffff811115612f0e57612f0e61260e565b612f2281612f1c8454612c58565b84612ea4565b602080601f831160018114612f575760008415612f3f5750858301515b600019600386901b1c1916600185901b178555612eec565b600085815260208120601f198616915b82811015612f8657888601518255948401946001909101908401612f67565b5085821015612fa45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561303157888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261301d818601836128a8565b968901969450505090860190600101612fdd565b509098975050505050505050565b60006001600160a01b03808916835267ffffffffffffffff8816602084015260e0604084015261307260e08401886128a8565b838103606085015261308481886128a8565b86516080860152602087015160a0860152925061309e9050565b80841660c084015250979650505050505050565b805161276a816127b2565b6000604082840312156130cf57600080fd5b6040516040810181811067ffffffffffffffff821117156130f2576130f261260e565b604052825181526020928301519281019290925250919050565b60006080828403121561311e57600080fd5b613126612624565b825181526020830151613138816127b2565b602082015261296b84604085016130bd565b60ff8416815260606020820152600061316660608301856128a8565b828103604084015261317881856128a8565b9695505050505050565b6001600160a01b038616815267ffffffffffffffff8516602082015260a0604082015260006131b460a08301866128a8565b82810360608401526131c681866128a8565b91505082151560808301529695505050505050565b6000604082840312156131ed57600080fd5b61274f83836130bd565b808202811582820484141761206657612066612c2b565b60008261322b57634e487b7160e01b600052601260045260246000fd5b500490565b600082601f83011261324157600080fd5b815161324f612d7f82612c8c565b81815284602083860101111561326457600080fd5b610c13826020830160208701612884565b600080600080600060a0868803121561328d57600080fd5b8551613298816127b2565b60208701516040880151919650945067ffffffffffffffff808211156132bd57600080fd5b9087019060a0828a0312156132d157600080fd5b6132d961264d565b825160ff811681146132ea57600080fd5b81526020830151828111156132fe57600080fd5b61330a8b828601613230565b60208301525060408301518281111561332257600080fd5b61332e8b828601613230565b6040830152506060830151606082015261334a608084016130b2565b6080820152606089015190955091508082111561336657600080fd5b5061337388828901613230565b925050608086015190509295509295909350565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a060808401526133bd60e08401826128a8565b90506060850151603f198483030160a08501526133da82826128a8565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b8181038181111561206657612066612c2b565b60006020828403121561342557600080fd5b815161274f8161271d565b60008351613442818460208801612884565b835190830190613456818360208801612884565b01949350505050565b600067ffffffffffffffff808816835286602084015260a0604084015260ff86511660a0840152602086015160a060c08501526134a06101408501826128a8565b905060408701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608583030160e08601526134db82826128a8565b915050606087015161010085015281608088015116610120850152838103606085015261350881876128a8565b925050508260808301529695505050505050565b60208152815160208201526001600160a01b03602083015116604082015260006040830151613557606084018267ffffffffffffffff169052565b50606083015160ff811660808401525060808301516101008060a08501526135836101208501836128a8565b915060a0850151601f198584030160c08601526135a083826128a8565b92505060c08501516135be60e086018267ffffffffffffffff169052565b5060e0949094015192909301919091525090565b6000602082840312156135e457600080fd5b815161274f816126a1565b60008251613601818460208701612884565b919091019291505056fea2646970667358221220669c04a92555ccc2b775d00f3a22152964af27f6460ddbe95b515ff1720f765364736f6c634300081600330000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000000000000000000000000000000000000000759e00000000000000000000000027af77a7b70df78e4f112c413a48c9784a27ec2a
Deployed Bytecode
0x6080604052600436106101e75760003560e01c80638da5cb5b11610102578063bb0b6a5311610095578063e3fbc36311610064578063e3fbc363146106aa578063ef264939146106b8578063f2fde38b146106da578063f3562c26146106fa57600080fd5b8063bb0b6a531461062a578063bc70b35414610657578063bd041c4d14610677578063ca5eb5e11461068a57600080fd5b8063a7b3ece4116100d1578063a7b3ece414610556578063a8e4fb90146105a1578063b67d5433146105c1578063b98bd0701461060a57600080fd5b80638da5cb5b146104aa57806391ddadf4146104c857806391ffc9b2146104f4578063a3ae02571461051457600080fd5b80635535d4611161017a5780635e9c67d8116101495780635e9c67d8146103fa5780636a302b771461041a578063715018a614610475578063872e411d1461048a57600080fd5b80635535d4611461035857806355651b0e14610378578063597cbd12146103985780635e280f11146103c657600080fd5b8063376cc2e1116101b6578063376cc2e11461026f5780633bd67dca146102aa5780633d6dc928146102bd5780634bf5d7e91461030957600080fd5b80630604d7dd146101f357806317442b70146102085780631fb4a2281461022f5780633400288b1461024f57600080fd5b366101ee57005b600080fd5b6102066102013660046126af565b61070f565b005b34801561021457600080fd5b50604080516001815260006020820152015b60405180910390f35b34801561023b57600080fd5b5061020661024a366004612732565b610741565b34801561025b57600080fd5b5061020661026a36600461276f565b610778565b34801561027b57600080fd5b5061029c61028a366004612799565b60026020526000908152604090205481565b604051908152602001610226565b6102066102b8366004612811565b61078e565b3480156102c957600080fd5b506102f17f00000000000000000000000027af77a7b70df78e4f112c413a48c9784a27ec2a81565b6040516001600160a01b039091168152602001610226565b34801561031557600080fd5b5060408051808201909152601b81527f6d6f64653d74696d657374616d702666726f6d3d64656661756c74000000000060208201525b60405161022691906128d4565b34801561036457600080fd5b5061034b6103733660046128f9565b610804565b34801561038457600080fd5b5061020661039336600461292c565b6108a9565b3480156103a457600080fd5b506008546103b39061ffff1681565b60405161ffff9091168152602001610226565b3480156103d257600080fd5b506102f17f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561040657600080fd5b506005546102f1906001600160a01b031681565b34801561042657600080fd5b50600954600a5461044f919067ffffffffffffffff808216916801000000000000000090041683565b6040805193845267ffffffffffffffff9283166020850152911690820152606001610226565b34801561048157600080fd5b50610206610953565b34801561049657600080fd5b506102066104a5366004612977565b610967565b3480156104b657600080fd5b506000546001600160a01b03166102f1565b3480156104d457600080fd5b506104dd6109a4565b60405165ffffffffffff9091168152602001610226565b34801561050057600080fd5b5061020661050f366004612732565b6109b3565b34801561052057600080fd5b5061053461052f3660046129bc565b610a24565b6040805182518152602080840151908201529181015190820152606001610226565b34801561056257600080fd5b50610591610571366004612a45565b600360209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610226565b3480156105ad57600080fd5b506001546102f1906001600160a01b031681565b3480156105cd57600080fd5b506105f57f000000000000000000000000000000000000000000000000000000000000759e81565b60405163ffffffff9091168152602001610226565b34801561061657600080fd5b50610206610625366004612a75565b610a48565b34801561063657600080fd5b5061029c610645366004612aea565b60046020526000908152604090205481565b34801561066357600080fd5b5061034b610672366004612b05565b610a62565b610206610685366004612b66565b610c1b565b34801561069657600080fd5b506102066106a5366004612732565b610e8a565b610206610201366004612b94565b3480156106c457600080fd5b506106cd610f22565b6040516102269190612c14565b3480156106e657600080fd5b506102066106f5366004612732565b6110bc565b34801561070657600080fd5b506106cd61114c565b6040517fa3ce824a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107496111dc565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6107806111dc565b61078a8282611236565b5050565b6005546001600160a01b0316336001600160a01b0316146107db576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680549060006107eb83612c41565b91905055506107fd858585858561128b565b5050505050565b60076020908152600092835260408084209091529082529020805461082890612c58565b80601f016020809104026020016040519081016040528092919081815260200182805461085490612c58565b80156108a15780601f10610876576101008083540402835291602001916108a1565b820191906000526020600020905b81548152906001019060200180831161088457829003601f168201915b505050505081565b6001546001600160a01b0316336001600160a01b0316146108f6576040517f5b0f85e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516009556020810151600a805460409093015167ffffffffffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909416921691909117919091179055565b61095b6111dc565b6109656000611352565b565b61096f6111dc565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff92909216919091179055565b60006109ae6113af565b905090565b6109bb6111dc565b600654156109f5576040517feebae33000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b61070f60405180606001604052806000815260200160008152602001600081525090565b610a506111dc565b61078a610a5d8284612cb4565b6113ba565b63ffffffff8416600090815260076020908152604080832061ffff87168452909152812080546060929190610a9690612c58565b80601f0160208091040260200160405190810160405280929190818152602001828054610ac290612c58565b8015610b0f5780601f10610ae457610100808354040283529160200191610b0f565b820191906000526020600020905b815481529060010190602001808311610af257829003601f168201915b505050505090508051600003610b5f5783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450610c139350505050565b6000839003610b6f579050610c13565b60028310610bed57610bb684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114cc92505050565b80610bc48460028188612dca565b604051602001610bd693929190612df4565b604051602081830303815290604052915050610c13565b8383604051639a6d49cd60e01b8152600401610c0a929190612e1c565b60405180910390fd5b949350505050565b600954600003610c57576040517fc748fea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610c616109a4565b600a5465ffffffffffff91909116915067ffffffffffffffff16811080610c9f5750600a5468010000000000000000900467ffffffffffffffff1681115b15610cd6576040517fd80bf02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337f00000000000000000000000027af77a7b70df78e4f112c413a48c9784a27ec2a6001600160a01b031614610d38576040517f46e52c4400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060810182526009548152600a5467ffffffffffffffff8082166020840152680100000000000000009091041691810191909152600083610d7e576000610d81565b60015b6040805160a08101825260ff83168152815160208181018452600080835281840192909252835180820185528281528385015286516060808501919091528782015167ffffffffffffffff16608085015284518082018652808601848152815285518084018752848152818401528551918201865234825291810183905293840191909152929350610e149288926114f8565b81516000908152600260205260408120805491610e3083612e61565b9091555050905160009081526003602090815260408083206001600160a01b0390971683529590529390932080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050565b610e926111dc565b6040517fca5eb5e10000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b158015610f0e57600080fd5b505af11580156107fd573d6000803e3d6000fd5b6040805180820190915260008082526020820152600954600003610f72576040517fc748fea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f7c6109a4565b600a5465ffffffffffff91909116915067ffffffffffffffff16811080610fba5750600a5468010000000000000000900467ffffffffffffffff1681115b15610ff1576040517fd80bf02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061108760006040518060a001604052806001600281111561101657611016612e4b565b60ff16815260408051602081810183526000808352818501929092528251808201845282815283850152600954606080860191909152600a5467ffffffffffffffff16608090950194909452825193840183528383018281528452825180820190935281835283019190915261173d565b90506040518060400160405280826040015183600001516110a89190612e7b565b815260200182602001518152509250505090565b6110c46111dc565b6001600160a01b0381166111405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c0a565b61114981611352565b50565b60408051808201909152600080825260208201526109ae60006040518060a001604052806001600281111561118357611183612e4b565b60ff168152604080516020818101835260008083528185019290925282518082018452828152838501526009546060850152600a5467ffffffffffffffff1660809094019390935281519283019091528082529061193c565b6000546001600160a01b031633146109655760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c0a565b63ffffffff8216600081815260046020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b60008060008060006112d287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b2192505050565b945094509450945094506113456040518061010001604052808c6001600160a01b031681526020018767ffffffffffffffff1681526020018681526020018581526020018a8152602001848152602001348461132e9190612e7b565b81526020018c6001600160a01b0316815250611b8d565b5050505050505050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006109ae42611dd3565b60005b8151811015611491576113ec8282815181106113db576113db612e8e565b6020026020010151604001516114cc565b8181815181106113fe576113fe612e8e565b6020026020010151604001516007600084848151811061142057611420612e8e565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061145a5761145a612e8e565b60200260200101516020015161ffff1661ffff16815260200190815260200160002090816114889190612ef4565b506001016113bd565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516114c19190612fb4565b60405180910390a150565b600281015161ffff811660031461078a5781604051639a6d49cd60e01b8152600401610c0a91906128d4565b61150484848484611e55565b90506115138160200151611ef2565b60006116156115206109a4565b606086015163ffffffff7f000000000000000000000000000000000000000000000000000000000000759e166000908152600760209081526040808320600184529091529020805465ffffffffffff9390931692889161160b9161158390612c58565b80601f01602080910402602001604051908101604052809291908181526020018280546115af90612c58565b80156115fc5780601f106115d1576101008083540402835291602001916115fc565b820191906000526020600020905b8154815290600101906020018083116115df57829003601f168201915b50505050508860200151611fb3565b866040015161206c565b600554835160808701518651604080518082018252885181526020808a01519082015290517fdd3acfcd0000000000000000000000000000000000000000000000000000000081529596506001600160a01b039094169463dd3acfcd94611687938c939092899290859060040161303f565b60806040518083038185885af11580156116a5573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116ca919061310c565b50600680549060006116db83612e61565b91905055508360600151856001600160a01b03167fc1bef9e33878816461aa6c2b21411bb2993d2d127ed1212fa50351e123c3061486600001518760200151886040015160405161172e9392919061314a565b60405180910390a35050505050565b61176160405180606001604052806000815260200160008152602001600081525090565b600061186061176e6109a4565b606087015163ffffffff7f000000000000000000000000000000000000000000000000000000000000759e166000908152600760209081526040808320600184529091529020805465ffffffffffff93909316928991611859916117d190612c58565b80601f01602080910402602001604051908101604052809291908181526020018280546117fd90612c58565b801561184a5780601f1061181f5761010080835404028352916020019161184a565b820191906000526020600020905b81548152906001019060200180831161182d57829003601f168201915b50505050508960200151611fb3565b600061206c565b600554608087015186516040517f77b2a5650000000000000000000000000000000000000000000000000000000081529394506000936001600160a01b03909316926377b2a565926118bb928c928891908b90600401613182565b6040805180830381865afa1580156118d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fb91906131db565b9050600061191088886000896020015161193c565b604080516060810182528451815260209485015194810194909452905190830152509695505050505050565b604080518082019091526000808252602082015260006119d760405180610100016040528087606001518152602001886001600160a01b031681526020016119826109a4565b65ffffffffffff1667ffffffffffffffff168152602001876000015160ff1681526020018760200151815260200187604001518152602001876080015167ffffffffffffffff168152602001868152506120a1565b63ffffffff7f000000000000000000000000000000000000000000000000000000000000759e16600090815260076020908152604080832060018452909152812080549293509091611ab19190611a2d90612c58565b80601f0160208091040260200160405190810160405280929190818152602001828054611a5990612c58565b8015611aa65780601f10611a7b57610100808354040283529160200191611aa6565b820191906000526020600020905b815481529060010190602001808311611a8957829003601f168201915b505050505085611fb3565b9050611ae07f000000000000000000000000000000000000000000000000000000000000759e838360006120ca565b600854815191945061271091611afa9161ffff16906131f7565b611b04919061320e565b83518490611b13908390612e7b565b905250919695505050505050565b600080611b636040518060a00160405280600060ff168152602001606081526020016060815260200160008152602001600067ffffffffffffffff1681525090565b6060600085806020019051810190611b7b9190613275565b939a9299509097509550909350915050565b611b956125c6565b6000611c296040518061010001604052808560400151815260200185600001516001600160a01b03168152602001856020015167ffffffffffffffff16815260200185606001516000015160ff1681526020018560600151602001518152602001856060015160400151815260200185606001516080015167ffffffffffffffff16815260200185608001518152506120a1565b905060004790507f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a4508560c001516040518060a001604052807f000000000000000000000000000000000000000000000000000000000000759e63ffffffff168152602001611cc47f000000000000000000000000000000000000000000000000000000000000759e6121ab565b81526020018681526020018860a00151815260200160001515815250306040518463ffffffff1660e01b8152600401611cfe929190613387565b60806040518083038185885af1158015611d1c573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611d41919061310c565b92506000818560c0015147611d569190612e7b565b611d609190613400565b90508015611dcb5760e08501516040516000916001600160a01b03169083156108fc0290849084818181858888f19350505050905080611dc957604051329083156108fc029084906000818181858888f19350505050158015611dc7573d6000803e3d6000fd5b505b505b505050919050565b600065ffffffffffff821115611e515760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201527f38206269747300000000000000000000000000000000000000000000000000006064820152608401610c0a565b5090565b611e7960405180606001604052806000815260200160008152602001600081525090565b6000611e8c86866000876020015161193c565b8051909150341015611ed65780516040517fa49e79ba0000000000000000000000000000000000000000000000000000000081523460048201526024810191909152604401610c0a565b8051611ee29034613400565b8252516040820152949350505050565b80156111495760007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7c9190613413565b905061078a6001600160a01b038216337f0000000000000000000000001a44076050125825900e736c501f859c50fe728c85612200565b60608251600003611fc5575080612066565b8151600003611fd5575081612066565b600283511080611fe6575060028251105b15612016576002835110611ffa5781611ffc565b825b604051639a6d49cd60e01b8152600401610c0a91906128d4565b61201f836114cc565b612028826114cc565b82612043600280855161203b9190613400565b85919061228e565b604051602001612054929190613430565b60405160208183030381529060405290505b92915050565b6060858585858560405160200161208795949392919061345f565b604051602081830303815290604052905095945050505050565b6060816040516020016120b4919061351c565b6040516020818303038152906040529050919050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161212d896121ab565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612162929190613387565b6040805180830381865afa15801561217e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a291906131db565b95945050505050565b63ffffffff811660009081526004602052604081205480612066576040517ff6ff4fb700000000000000000000000000000000000000000000000000000000815263ffffffff84166004820152602401610c0a565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526122889085906123b6565b50505050565b60608161229c81601f612e7b565b10156122ea5760405162461bcd60e51b815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610c0a565b6122f48284612e7b565b845110156123445760405162461bcd60e51b815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610c0a565b60608215801561236357604051915060008252602082016040526123ad565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561239c578051835260209283019201612384565b5050858452601f01601f1916604052505b50949350505050565b600061240b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124a39092919063ffffffff16565b905080516000148061242c57508080602001905181019061242c91906135d2565b61249e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610c0a565b505050565b6060610c13848460008585600080866001600160a01b031685876040516124ca91906135ef565b60006040518083038185875af1925050503d8060008114612507576040519150601f19603f3d011682016040523d82523d6000602084013e61250c565b606091505b509150915061251d87838387612528565b979650505050505050565b60608315612597578251600003612590576001600160a01b0385163b6125905760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c0a565b5081610c13565b610c1383838151156125ac5781518083602001fd5b8060405162461bcd60e51b8152600401610c0a91906128d4565b604051806060016040528060008019168152602001600067ffffffffffffffff168152602001612609604051806040016040528060008152602001600081525090565b905290565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156126475761264761260e565b60405290565b60405160a0810167ffffffffffffffff811182821017156126475761264761260e565b604051601f8201601f1916810167ffffffffffffffff811182821017156126995761269961260e565b604052919050565b801515811461114957600080fd5b6000608082840312156126c157600080fd5b6040516080810181811067ffffffffffffffff821117156126e4576126e461260e565b806040525082358152602083013560208201526040830135612705816126a1565b60408201526060928301359281019290925250919050565b6001600160a01b038116811461114957600080fd5b60006020828403121561274457600080fd5b813561274f8161271d565b9392505050565b803563ffffffff8116811461276a57600080fd5b919050565b6000806040838503121561278257600080fd5b61278b83612756565b946020939093013593505050565b6000602082840312156127ab57600080fd5b5035919050565b67ffffffffffffffff8116811461114957600080fd5b60008083601f8401126127da57600080fd5b50813567ffffffffffffffff8111156127f257600080fd5b60208301915083602082850101111561280a57600080fd5b9250929050565b60008060008060006080868803121561282957600080fd5b85356128348161271d565b94506020860135612844816127b2565b935060408601359250606086013567ffffffffffffffff81111561286757600080fd5b612873888289016127c8565b969995985093965092949392505050565b60005b8381101561289f578181015183820152602001612887565b50506000910152565b600081518084526128c0816020860160208601612884565b601f01601f19169290920160200192915050565b60208152600061274f60208301846128a8565b803561ffff8116811461276a57600080fd5b6000806040838503121561290c57600080fd5b61291583612756565b9150612923602084016128e7565b90509250929050565b60006060828403121561293e57600080fd5b612946612624565b823581526020830135612958816127b2565b6020820152604083013561296b816127b2565b60408201529392505050565b60006020828403121561298957600080fd5b61274f826128e7565b600060a082840312156129a457600080fd5b50919050565b6000604082840312156129a457600080fd5b600080600080608085870312156129d257600080fd5b84356129dd8161271d565b9350602085013567ffffffffffffffff808211156129fa57600080fd5b612a0688838901612992565b94506040870135915080821115612a1c57600080fd5b50612a29878288016129aa565b9250506060850135612a3a816126a1565b939692955090935050565b60008060408385031215612a5857600080fd5b823591506020830135612a6a8161271d565b809150509250929050565b60008060208385031215612a8857600080fd5b823567ffffffffffffffff80821115612aa057600080fd5b818501915085601f830112612ab457600080fd5b813581811115612ac357600080fd5b8660208260051b8501011115612ad857600080fd5b60209290920196919550909350505050565b600060208284031215612afc57600080fd5b61274f82612756565b60008060008060608587031215612b1b57600080fd5b612b2485612756565b9350612b32602086016128e7565b9250604085013567ffffffffffffffff811115612b4e57600080fd5b612b5a878288016127c8565b95989497509550505050565b60008060408385031215612b7957600080fd5b8235612b848161271d565b91506020830135612a6a816126a1565b600080600083850360a0811215612baa57600080fd5b843567ffffffffffffffff80821115612bc257600080fd5b612bce88838901612992565b95506020870135915080821115612be457600080fd5b50612bf1878288016129aa565b9350506060603f1982011215612c0657600080fd5b506040840190509250925092565b815181526020808301519082015260408101612066565b634e487b7160e01b600052601160045260246000fd5b600081612c5057612c50612c2b565b506000190190565b600181811c90821680612c6c57607f821691505b6020821081036129a457634e487b7160e01b600052602260045260246000fd5b600067ffffffffffffffff821115612ca657612ca661260e565b50601f01601f191660200190565b600067ffffffffffffffff80841115612ccf57612ccf61260e565b8360051b6020612ce0818301612670565b868152918501918181019036841115612cf857600080fd5b865b84811015612dbe57803586811115612d125760008081fd5b88016060368290031215612d265760008081fd5b612d2e612624565b612d3782612756565b8152612d448683016128e7565b8682015260408083013589811115612d5c5760008081fd5b929092019136601f840112612d715760008081fd5b8235612d84612d7f82612c8c565b612670565b8181523689838701011115612d995760008081fd5b818986018a830137600091810189019190915290820152845250918301918301612cfa565b50979650505050505050565b60008085851115612dda57600080fd5b83861115612de757600080fd5b5050820193919092039150565b60008451612e06818460208901612884565b8201838582376000930192835250909392505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052602160045260246000fd5b60006000198203612e7457612e74612c2b565b5060010190565b8082018082111561206657612066612c2b565b634e487b7160e01b600052603260045260246000fd5b601f82111561249e576000816000526020600020601f850160051c81016020861015612ecd5750805b601f850160051c820191505b81811015612eec57828155600101612ed9565b505050505050565b815167ffffffffffffffff811115612f0e57612f0e61260e565b612f2281612f1c8454612c58565b84612ea4565b602080601f831160018114612f575760008415612f3f5750858301515b600019600386901b1c1916600185901b178555612eec565b600085815260208120601f198616915b82811015612f8657888601518255948401946001909101908401612f67565b5085821015612fa45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561303157888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261301d818601836128a8565b968901969450505090860190600101612fdd565b509098975050505050505050565b60006001600160a01b03808916835267ffffffffffffffff8816602084015260e0604084015261307260e08401886128a8565b838103606085015261308481886128a8565b86516080860152602087015160a0860152925061309e9050565b80841660c084015250979650505050505050565b805161276a816127b2565b6000604082840312156130cf57600080fd5b6040516040810181811067ffffffffffffffff821117156130f2576130f261260e565b604052825181526020928301519281019290925250919050565b60006080828403121561311e57600080fd5b613126612624565b825181526020830151613138816127b2565b602082015261296b84604085016130bd565b60ff8416815260606020820152600061316660608301856128a8565b828103604084015261317881856128a8565b9695505050505050565b6001600160a01b038616815267ffffffffffffffff8516602082015260a0604082015260006131b460a08301866128a8565b82810360608401526131c681866128a8565b91505082151560808301529695505050505050565b6000604082840312156131ed57600080fd5b61274f83836130bd565b808202811582820484141761206657612066612c2b565b60008261322b57634e487b7160e01b600052601260045260246000fd5b500490565b600082601f83011261324157600080fd5b815161324f612d7f82612c8c565b81815284602083860101111561326457600080fd5b610c13826020830160208701612884565b600080600080600060a0868803121561328d57600080fd5b8551613298816127b2565b60208701516040880151919650945067ffffffffffffffff808211156132bd57600080fd5b9087019060a0828a0312156132d157600080fd5b6132d961264d565b825160ff811681146132ea57600080fd5b81526020830151828111156132fe57600080fd5b61330a8b828601613230565b60208301525060408301518281111561332257600080fd5b61332e8b828601613230565b6040830152506060830151606082015261334a608084016130b2565b6080820152606089015190955091508082111561336657600080fd5b5061337388828901613230565b925050608086015190509295509295909350565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a060808401526133bd60e08401826128a8565b90506060850151603f198483030160a08501526133da82826128a8565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b8181038181111561206657612066612c2b565b60006020828403121561342557600080fd5b815161274f8161271d565b60008351613442818460208801612884565b835190830190613456818360208801612884565b01949350505050565b600067ffffffffffffffff808816835286602084015260a0604084015260ff86511660a0840152602086015160a060c08501526134a06101408501826128a8565b905060408701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608583030160e08601526134db82826128a8565b915050606087015161010085015281608088015116610120850152838103606085015261350881876128a8565b925050508260808301529695505050505050565b60208152815160208201526001600160a01b03602083015116604082015260006040830151613557606084018267ffffffffffffffff169052565b50606083015160ff811660808401525060808301516101008060a08501526135836101208501836128a8565b915060a0850151601f198584030160c08601526135a083826128a8565b92505060c08501516135be60e086018267ffffffffffffffff169052565b5060e0949094015192909301919091525090565b6000602082840312156135e457600080fd5b815161274f816126a1565b60008251613601818460208701612884565b919091019291505056fea2646970667358221220669c04a92555ccc2b775d00f3a22152964af27f6460ddbe95b515ff1720f765364736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000000000000000000000000000000000000000759e00000000000000000000000027af77a7b70df78e4f112c413a48c9784a27ec2a
-----Decoded View---------------
Arg [0] : _endpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [1] : _mainEid (uint32): 30110
Arg [2] : _vote (address): 0x27Af77A7B70DF78E4F112c413A48C9784a27EC2a
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [1] : 000000000000000000000000000000000000000000000000000000000000759e
Arg [2] : 00000000000000000000000027af77a7b70df78e4f112c413a48c9784a27ec2a
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.