diff --git a/deploy/deploy_ai_service_registry.ts b/deploy/deploy_ai_service_registry.ts new file mode 100644 index 00000000..39a66dc8 --- /dev/null +++ b/deploy/deploy_ai_service_registry.ts @@ -0,0 +1,25 @@ +import {HardhatRuntimeEnvironment} from "hardhat/types" +import {DeployFunction} from "hardhat-deploy/types" + +import ContractDeployer from "../utils/deployer" + +const func: DeployFunction = async function(hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre // Get the deployments and getNamedAccounts which are provided by hardhat-deploy + + const {deployer} = await getNamedAccounts() // Fetch named accounts from hardhat.config.ts + + const contractDeployer = new ContractDeployer(deployer, deployments) + const controller = await contractDeployer.fetchDeployedController() + + const deploy = contractDeployer.deploy.bind(contractDeployer) + + await deploy({ + contract: "ServiceRegistry", + name: "AIServiceRegistry", + args: [controller.address], + proxy: true + }) +} + +func.tags = ["AI_SERVICE_REGISTRY"] +export default func diff --git a/deployments/arbitrumMainnet/AIServiceRegistry.json b/deployments/arbitrumMainnet/AIServiceRegistry.json new file mode 100644 index 00000000..d95850fa --- /dev/null +++ b/deployments/arbitrumMainnet/AIServiceRegistry.json @@ -0,0 +1,183 @@ +{ + "address": "0x72a02a76b6FAb955E7e0e09830Ea28972d39c629", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_targetContractId", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "param", + "type": "string" + } + ], + "name": "ParameterUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "SetController", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract IController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetContractId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x085c8ab3b2e64697948e27af268253714531e8a031bafa539e51a9b8b33f686b", + "receipt": { + "to": null, + "from": "0xF5282864EC36871c36BF682aFE1C3f180D4f7902", + "contractAddress": "0x72a02a76b6FAb955E7e0e09830Ea28972d39c629", + "transactionIndex": 2, + "gasUsed": "524984", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1cafbdbcee03bf566efb3c5bb4332cdb7037dce97d8ee84b250b6d353cdb57f0", + "transactionHash": "0x085c8ab3b2e64697948e27af268253714531e8a031bafa539e51a9b8b33f686b", + "logs": [], + "blockNumber": 202080807, + "cumulativeGasUsed": "828867", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD8E8328501E9645d16Cf49539efC04f734606ee4", + "0xf27e2cb38ea1af32b644874e3108325b67950f98d72767970324abc0538e0373" + ], + "numDeployments": 1, + "solcInputHash": "e0424c78571e350313a9f65dd4baea4e", + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_targetContractId\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"param\",\"type\":\"string\"}],\"name\":\"ParameterUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"SetController\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"setController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetContractId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_controller\":\"Address of Controller that this contract will be registered with\",\"_targetContractId\":\"contract ID of the target contract\"}},\"setController(address)\":{\"params\":{\"_controller\":\"Controller contract address\"}}},\"title\":\"ManagerProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address. Also, sets the contract ID of the target contract that function calls will be executed on.\"},\"setController(address)\":{\"notice\":\"Set controller. Only callable by current controller\"}},\"notice\":\"A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context. The target contract is a Manager contract that is registered with the Controller.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ManagerProxy.sol\":\"ManagerProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/IController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./zeppelin/Pausable.sol\\\";\\n\\nabstract contract IController is Pausable {\\n event SetContractInfo(bytes32 id, address contractAddress, bytes20 gitCommitHash);\\n\\n function setContractInfo(\\n bytes32 _id,\\n address _contractAddress,\\n bytes20 _gitCommitHash\\n ) external virtual;\\n\\n function updateController(bytes32 _id, address _controller) external virtual;\\n\\n function getContract(bytes32 _id) public view virtual returns (address);\\n}\\n\",\"keccak256\":\"0x34ea30a2b44d0cbec58fc1d703476ff0085b0fdadab0cd65c35c00b8867f7546\",\"license\":\"MIT\"},\"contracts/IManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\ninterface IManager {\\n event SetController(address controller);\\n event ParameterUpdate(string param);\\n\\n function setController(address _controller) external;\\n}\\n\",\"keccak256\":\"0xc179e4cecc593741514237d5194b4aaac6b829789629fa19ed04f572a8530481\",\"license\":\"MIT\"},\"contracts/Manager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./IManager.sol\\\";\\nimport \\\"./IController.sol\\\";\\n\\ncontract Manager is IManager {\\n // Controller that contract is registered with\\n IController public controller;\\n\\n // Check if sender is controller\\n modifier onlyController() {\\n _onlyController();\\n _;\\n }\\n\\n // Check if sender is controller owner\\n modifier onlyControllerOwner() {\\n _onlyControllerOwner();\\n _;\\n }\\n\\n // Check if controller is not paused\\n modifier whenSystemNotPaused() {\\n _whenSystemNotPaused();\\n _;\\n }\\n\\n // Check if controller is paused\\n modifier whenSystemPaused() {\\n _whenSystemPaused();\\n _;\\n }\\n\\n constructor(address _controller) {\\n controller = IController(_controller);\\n }\\n\\n /**\\n * @notice Set controller. Only callable by current controller\\n * @param _controller Controller contract address\\n */\\n function setController(address _controller) external onlyController {\\n controller = IController(_controller);\\n\\n emit SetController(_controller);\\n }\\n\\n function _onlyController() private view {\\n require(msg.sender == address(controller), \\\"caller must be Controller\\\");\\n }\\n\\n function _onlyControllerOwner() private view {\\n require(msg.sender == controller.owner(), \\\"caller must be Controller owner\\\");\\n }\\n\\n function _whenSystemNotPaused() private view {\\n require(!controller.paused(), \\\"system is paused\\\");\\n }\\n\\n function _whenSystemPaused() private view {\\n require(controller.paused(), \\\"system is not paused\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc415e3f42da9f82ddd5953031f3f26aed824368fcc34d3b8a17015bfe80dc109\",\"license\":\"MIT\"},\"contracts/ManagerProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./ManagerProxyTarget.sol\\\";\\n\\n/**\\n * @title ManagerProxy\\n * @notice A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context.\\n The target contract is a Manager contract that is registered with the Controller.\\n * @dev Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee\\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\\n potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits\\n from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits\\n from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead\\n of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless\\n of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract\\n because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract\\n */\\ncontract ManagerProxy is ManagerProxyTarget {\\n /**\\n * @notice ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address.\\n * Also, sets the contract ID of the target contract that function calls will be executed on.\\n * @param _controller Address of Controller that this contract will be registered with\\n * @param _targetContractId contract ID of the target contract\\n */\\n constructor(address _controller, bytes32 _targetContractId) Manager(_controller) {\\n targetContractId = _targetContractId;\\n }\\n\\n /**\\n * @notice Fallback function that delegates calls to target contract when there is no msg.data\\n */\\n receive() external payable {\\n _fallback();\\n }\\n\\n /**\\n * @notice Fallback function that delegates calls to target contract when there is msg.data\\n */\\n fallback() external payable {\\n _fallback();\\n }\\n\\n /**\\n * @dev Uses delegatecall to execute function calls on this proxy contract's target contract using its own storage context.\\n This fallback function will look up the address of the target contract using the Controller and the target contract ID.\\n It will then use the calldata for a function call as the data payload for a delegatecall on the target contract. The return value\\n of the executed function call will also be returned\\n */\\n function _fallback() private {\\n address target = controller.getContract(targetContractId);\\n require(target != address(0), \\\"target contract must be registered\\\");\\n\\n assembly {\\n // Solidity keeps a free memory pointer at position 0x40 in memory\\n let freeMemoryPtrPosition := 0x40\\n // Load the free memory pointer\\n let calldataMemoryOffset := mload(freeMemoryPtrPosition)\\n // Update free memory pointer to after memory space we reserve for calldata\\n mstore(freeMemoryPtrPosition, add(calldataMemoryOffset, calldatasize()))\\n // Copy calldata (method signature and params of the call) to memory\\n calldatacopy(calldataMemoryOffset, 0x0, calldatasize())\\n\\n // Call method on target contract using calldata which is loaded into memory\\n let ret := delegatecall(gas(), target, calldataMemoryOffset, calldatasize(), 0, 0)\\n\\n // Load the free memory pointer\\n let returndataMemoryOffset := mload(freeMemoryPtrPosition)\\n // Update free memory pointer to after memory space we reserve for returndata\\n mstore(freeMemoryPtrPosition, add(returndataMemoryOffset, returndatasize()))\\n // Copy returndata (result of the method invoked by the delegatecall) to memory\\n returndatacopy(returndataMemoryOffset, 0x0, returndatasize())\\n\\n switch ret\\n case 0 {\\n // Method call failed - revert\\n // Return any error message stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\\n revert(returndataMemoryOffset, returndatasize())\\n }\\n default {\\n // Return result of method call stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\\n return(returndataMemoryOffset, returndatasize())\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x59d1851363df8c385106e513652ace0d3903382df8b9fed03906650c5484158e\",\"license\":\"MIT\"},\"contracts/ManagerProxyTarget.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Manager.sol\\\";\\n\\n/**\\n * @title ManagerProxyTarget\\n * @notice The base contract that target contracts used by a proxy contract should inherit from\\n * @dev Both the target contract and the proxy contract (implemented as ManagerProxy) MUST inherit from ManagerProxyTarget in order to guarantee\\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\\n potentially break the delegate proxy upgradeability mechanism\\n */\\nabstract contract ManagerProxyTarget is Manager {\\n // Used to look up target contract address in controller's registry\\n bytes32 public targetContractId;\\n}\\n\",\"keccak256\":\"0x920bcc2def240e06272dc06cbcb9f12976f1698cd4f1020c165af25ee837e553\",\"license\":\"MIT\"},\"contracts/zeppelin/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\ncontract Ownable {\\n address public owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n require(newOwner != address(0));\\n emit OwnershipTransferred(owner, newOwner);\\n owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x64f114689f2f161c4a4b8fc8442ab914436a33e6021bf17401eaeac73319a419\",\"license\":\"MIT\"},\"contracts/zeppelin/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @title Pausable\\n * @dev Base contract which allows children to implement an emergency stop mechanism.\\n */\\ncontract Pausable is Ownable {\\n event Pause();\\n event Unpause();\\n\\n bool public paused;\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!paused);\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(paused);\\n _;\\n }\\n\\n /**\\n * @dev called by the owner to pause, triggers stopped state\\n */\\n function pause() public onlyOwner whenNotPaused {\\n paused = true;\\n emit Pause();\\n }\\n\\n /**\\n * @dev called by the owner to unpause, returns to normal state\\n */\\n function unpause() public onlyOwner whenPaused {\\n paused = false;\\n emit Unpause();\\n }\\n}\\n\",\"keccak256\":\"0xe9635fcac46c22547a08f6977a8c75e7341411f1201f60bdd4c79c26e6c286ef\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516103d93803806103d983398101604081905261002f91610058565b600080546001600160a01b0319166001600160a01b039390931692909217909155600155610092565b6000806040838503121561006b57600080fd5b82516001600160a01b038116811461008257600080fd5b6020939093015192949293505050565b610338806100a16000396000f3fe6080604052600436106100385760003560e01c806351720b411461004f57806392eefe9b14610078578063f77c47911461009857610047565b36610047576100456100d0565b005b6100456100d0565b34801561005b57600080fd5b5061006560015481565b6040519081526020015b60405180910390f35b34801561008457600080fd5b506100456100933660046102c1565b6101f1565b3480156100a457600080fd5b506000546100b8906001600160a01b031681565b6040516001600160a01b03909116815260200161006f565b60008054600154604051631c2d8fb360e31b81526001600160a01b039092169163e16c7d98916101069160040190815260200190565b60206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015691906102e5565b90506001600160a01b0381166101be5760405162461bcd60e51b815260206004820152602260248201527f74617267657420636f6e7472616374206d757374206265207265676973746572604482015261195960f21b60648201526084015b60405180910390fd5b60408051368101825236600082376000803683865af4905081513d810183523d6000823e8180156101ed573d82f35b3d82fd5b6101f961024d565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102a75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c65720000000000000060448201526064016101b5565b565b6001600160a01b03811681146102be57600080fd5b50565b6000602082840312156102d357600080fd5b81356102de816102a9565b9392505050565b6000602082840312156102f757600080fd5b81516102de816102a956fea2646970667358221220274e52a3b60c7dff1cad0833c349004759648080531c69a484b94b22224cfa1164736f6c63430008090033", + "deployedBytecode": "0x6080604052600436106100385760003560e01c806351720b411461004f57806392eefe9b14610078578063f77c47911461009857610047565b36610047576100456100d0565b005b6100456100d0565b34801561005b57600080fd5b5061006560015481565b6040519081526020015b60405180910390f35b34801561008457600080fd5b506100456100933660046102c1565b6101f1565b3480156100a457600080fd5b506000546100b8906001600160a01b031681565b6040516001600160a01b03909116815260200161006f565b60008054600154604051631c2d8fb360e31b81526001600160a01b039092169163e16c7d98916101069160040190815260200190565b60206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015691906102e5565b90506001600160a01b0381166101be5760405162461bcd60e51b815260206004820152602260248201527f74617267657420636f6e7472616374206d757374206265207265676973746572604482015261195960f21b60648201526084015b60405180910390fd5b60408051368101825236600082376000803683865af4905081513d810183523d6000823e8180156101ed573d82f35b3d82fd5b6101f961024d565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102a75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c65720000000000000060448201526064016101b5565b565b6001600160a01b03811681146102be57600080fd5b50565b6000602082840312156102d357600080fd5b81356102de816102a9565b9392505050565b6000602082840312156102f757600080fd5b81516102de816102a956fea2646970667358221220274e52a3b60c7dff1cad0833c349004759648080531c69a484b94b22224cfa1164736f6c63430008090033", + "devdoc": { + "details": "Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_controller": "Address of Controller that this contract will be registered with", + "_targetContractId": "contract ID of the target contract" + } + }, + "setController(address)": { + "params": { + "_controller": "Controller contract address" + } + } + }, + "title": "ManagerProxy", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address. Also, sets the contract ID of the target contract that function calls will be executed on." + }, + "setController(address)": { + "notice": "Set controller. Only callable by current controller" + } + }, + "notice": "A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context. The target contract is a Manager contract that is registered with the Controller.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 18792, + "contract": "contracts/ManagerProxy.sol:ManagerProxy", + "label": "controller", + "offset": 0, + "slot": "0", + "type": "t_contract(IController)18767" + }, + { + "astId": 18974, + "contract": "contracts/ManagerProxy.sol:ManagerProxy", + "label": "targetContractId", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "types": { + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IController)18767": { + "encoding": "inplace", + "label": "contract IController", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/arbitrumMainnet/AIServiceRegistryProxy.json b/deployments/arbitrumMainnet/AIServiceRegistryProxy.json new file mode 100644 index 00000000..4eff9fa3 --- /dev/null +++ b/deployments/arbitrumMainnet/AIServiceRegistryProxy.json @@ -0,0 +1,183 @@ +{ + "address": "0x72a02a76b6FAb955E7e0e09830Ea28972d39c629", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_targetContractId", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "param", + "type": "string" + } + ], + "name": "ParameterUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "SetController", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract IController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetContractId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x085c8ab3b2e64697948e27af268253714531e8a031bafa539e51a9b8b33f686b", + "receipt": { + "to": null, + "from": "0xF5282864EC36871c36BF682aFE1C3f180D4f7902", + "contractAddress": "0x72a02a76b6FAb955E7e0e09830Ea28972d39c629", + "transactionIndex": 2, + "gasUsed": "524984", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1cafbdbcee03bf566efb3c5bb4332cdb7037dce97d8ee84b250b6d353cdb57f0", + "transactionHash": "0x085c8ab3b2e64697948e27af268253714531e8a031bafa539e51a9b8b33f686b", + "logs": [], + "blockNumber": 202080807, + "cumulativeGasUsed": "828867", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD8E8328501E9645d16Cf49539efC04f734606ee4", + "0xf27e2cb38ea1af32b644874e3108325b67950f98d72767970324abc0538e0373" + ], + "numDeployments": 3, + "solcInputHash": "e0424c78571e350313a9f65dd4baea4e", + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_targetContractId\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"param\",\"type\":\"string\"}],\"name\":\"ParameterUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"SetController\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"setController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetContractId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_controller\":\"Address of Controller that this contract will be registered with\",\"_targetContractId\":\"contract ID of the target contract\"}},\"setController(address)\":{\"params\":{\"_controller\":\"Controller contract address\"}}},\"title\":\"ManagerProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address. Also, sets the contract ID of the target contract that function calls will be executed on.\"},\"setController(address)\":{\"notice\":\"Set controller. Only callable by current controller\"}},\"notice\":\"A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context. The target contract is a Manager contract that is registered with the Controller.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ManagerProxy.sol\":\"ManagerProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/IController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./zeppelin/Pausable.sol\\\";\\n\\nabstract contract IController is Pausable {\\n event SetContractInfo(bytes32 id, address contractAddress, bytes20 gitCommitHash);\\n\\n function setContractInfo(\\n bytes32 _id,\\n address _contractAddress,\\n bytes20 _gitCommitHash\\n ) external virtual;\\n\\n function updateController(bytes32 _id, address _controller) external virtual;\\n\\n function getContract(bytes32 _id) public view virtual returns (address);\\n}\\n\",\"keccak256\":\"0x34ea30a2b44d0cbec58fc1d703476ff0085b0fdadab0cd65c35c00b8867f7546\",\"license\":\"MIT\"},\"contracts/IManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\ninterface IManager {\\n event SetController(address controller);\\n event ParameterUpdate(string param);\\n\\n function setController(address _controller) external;\\n}\\n\",\"keccak256\":\"0xc179e4cecc593741514237d5194b4aaac6b829789629fa19ed04f572a8530481\",\"license\":\"MIT\"},\"contracts/Manager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./IManager.sol\\\";\\nimport \\\"./IController.sol\\\";\\n\\ncontract Manager is IManager {\\n // Controller that contract is registered with\\n IController public controller;\\n\\n // Check if sender is controller\\n modifier onlyController() {\\n _onlyController();\\n _;\\n }\\n\\n // Check if sender is controller owner\\n modifier onlyControllerOwner() {\\n _onlyControllerOwner();\\n _;\\n }\\n\\n // Check if controller is not paused\\n modifier whenSystemNotPaused() {\\n _whenSystemNotPaused();\\n _;\\n }\\n\\n // Check if controller is paused\\n modifier whenSystemPaused() {\\n _whenSystemPaused();\\n _;\\n }\\n\\n constructor(address _controller) {\\n controller = IController(_controller);\\n }\\n\\n /**\\n * @notice Set controller. Only callable by current controller\\n * @param _controller Controller contract address\\n */\\n function setController(address _controller) external onlyController {\\n controller = IController(_controller);\\n\\n emit SetController(_controller);\\n }\\n\\n function _onlyController() private view {\\n require(msg.sender == address(controller), \\\"caller must be Controller\\\");\\n }\\n\\n function _onlyControllerOwner() private view {\\n require(msg.sender == controller.owner(), \\\"caller must be Controller owner\\\");\\n }\\n\\n function _whenSystemNotPaused() private view {\\n require(!controller.paused(), \\\"system is paused\\\");\\n }\\n\\n function _whenSystemPaused() private view {\\n require(controller.paused(), \\\"system is not paused\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc415e3f42da9f82ddd5953031f3f26aed824368fcc34d3b8a17015bfe80dc109\",\"license\":\"MIT\"},\"contracts/ManagerProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./ManagerProxyTarget.sol\\\";\\n\\n/**\\n * @title ManagerProxy\\n * @notice A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context.\\n The target contract is a Manager contract that is registered with the Controller.\\n * @dev Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee\\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\\n potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits\\n from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits\\n from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead\\n of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless\\n of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract\\n because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract\\n */\\ncontract ManagerProxy is ManagerProxyTarget {\\n /**\\n * @notice ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address.\\n * Also, sets the contract ID of the target contract that function calls will be executed on.\\n * @param _controller Address of Controller that this contract will be registered with\\n * @param _targetContractId contract ID of the target contract\\n */\\n constructor(address _controller, bytes32 _targetContractId) Manager(_controller) {\\n targetContractId = _targetContractId;\\n }\\n\\n /**\\n * @notice Fallback function that delegates calls to target contract when there is no msg.data\\n */\\n receive() external payable {\\n _fallback();\\n }\\n\\n /**\\n * @notice Fallback function that delegates calls to target contract when there is msg.data\\n */\\n fallback() external payable {\\n _fallback();\\n }\\n\\n /**\\n * @dev Uses delegatecall to execute function calls on this proxy contract's target contract using its own storage context.\\n This fallback function will look up the address of the target contract using the Controller and the target contract ID.\\n It will then use the calldata for a function call as the data payload for a delegatecall on the target contract. The return value\\n of the executed function call will also be returned\\n */\\n function _fallback() private {\\n address target = controller.getContract(targetContractId);\\n require(target != address(0), \\\"target contract must be registered\\\");\\n\\n assembly {\\n // Solidity keeps a free memory pointer at position 0x40 in memory\\n let freeMemoryPtrPosition := 0x40\\n // Load the free memory pointer\\n let calldataMemoryOffset := mload(freeMemoryPtrPosition)\\n // Update free memory pointer to after memory space we reserve for calldata\\n mstore(freeMemoryPtrPosition, add(calldataMemoryOffset, calldatasize()))\\n // Copy calldata (method signature and params of the call) to memory\\n calldatacopy(calldataMemoryOffset, 0x0, calldatasize())\\n\\n // Call method on target contract using calldata which is loaded into memory\\n let ret := delegatecall(gas(), target, calldataMemoryOffset, calldatasize(), 0, 0)\\n\\n // Load the free memory pointer\\n let returndataMemoryOffset := mload(freeMemoryPtrPosition)\\n // Update free memory pointer to after memory space we reserve for returndata\\n mstore(freeMemoryPtrPosition, add(returndataMemoryOffset, returndatasize()))\\n // Copy returndata (result of the method invoked by the delegatecall) to memory\\n returndatacopy(returndataMemoryOffset, 0x0, returndatasize())\\n\\n switch ret\\n case 0 {\\n // Method call failed - revert\\n // Return any error message stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\\n revert(returndataMemoryOffset, returndatasize())\\n }\\n default {\\n // Return result of method call stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\\n return(returndataMemoryOffset, returndatasize())\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x59d1851363df8c385106e513652ace0d3903382df8b9fed03906650c5484158e\",\"license\":\"MIT\"},\"contracts/ManagerProxyTarget.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Manager.sol\\\";\\n\\n/**\\n * @title ManagerProxyTarget\\n * @notice The base contract that target contracts used by a proxy contract should inherit from\\n * @dev Both the target contract and the proxy contract (implemented as ManagerProxy) MUST inherit from ManagerProxyTarget in order to guarantee\\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\\n potentially break the delegate proxy upgradeability mechanism\\n */\\nabstract contract ManagerProxyTarget is Manager {\\n // Used to look up target contract address in controller's registry\\n bytes32 public targetContractId;\\n}\\n\",\"keccak256\":\"0x920bcc2def240e06272dc06cbcb9f12976f1698cd4f1020c165af25ee837e553\",\"license\":\"MIT\"},\"contracts/zeppelin/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\ncontract Ownable {\\n address public owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n require(newOwner != address(0));\\n emit OwnershipTransferred(owner, newOwner);\\n owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x64f114689f2f161c4a4b8fc8442ab914436a33e6021bf17401eaeac73319a419\",\"license\":\"MIT\"},\"contracts/zeppelin/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @title Pausable\\n * @dev Base contract which allows children to implement an emergency stop mechanism.\\n */\\ncontract Pausable is Ownable {\\n event Pause();\\n event Unpause();\\n\\n bool public paused;\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!paused);\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(paused);\\n _;\\n }\\n\\n /**\\n * @dev called by the owner to pause, triggers stopped state\\n */\\n function pause() public onlyOwner whenNotPaused {\\n paused = true;\\n emit Pause();\\n }\\n\\n /**\\n * @dev called by the owner to unpause, returns to normal state\\n */\\n function unpause() public onlyOwner whenPaused {\\n paused = false;\\n emit Unpause();\\n }\\n}\\n\",\"keccak256\":\"0xe9635fcac46c22547a08f6977a8c75e7341411f1201f60bdd4c79c26e6c286ef\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516103d93803806103d983398101604081905261002f91610058565b600080546001600160a01b0319166001600160a01b039390931692909217909155600155610092565b6000806040838503121561006b57600080fd5b82516001600160a01b038116811461008257600080fd5b6020939093015192949293505050565b610338806100a16000396000f3fe6080604052600436106100385760003560e01c806351720b411461004f57806392eefe9b14610078578063f77c47911461009857610047565b36610047576100456100d0565b005b6100456100d0565b34801561005b57600080fd5b5061006560015481565b6040519081526020015b60405180910390f35b34801561008457600080fd5b506100456100933660046102c1565b6101f1565b3480156100a457600080fd5b506000546100b8906001600160a01b031681565b6040516001600160a01b03909116815260200161006f565b60008054600154604051631c2d8fb360e31b81526001600160a01b039092169163e16c7d98916101069160040190815260200190565b60206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015691906102e5565b90506001600160a01b0381166101be5760405162461bcd60e51b815260206004820152602260248201527f74617267657420636f6e7472616374206d757374206265207265676973746572604482015261195960f21b60648201526084015b60405180910390fd5b60408051368101825236600082376000803683865af4905081513d810183523d6000823e8180156101ed573d82f35b3d82fd5b6101f961024d565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102a75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c65720000000000000060448201526064016101b5565b565b6001600160a01b03811681146102be57600080fd5b50565b6000602082840312156102d357600080fd5b81356102de816102a9565b9392505050565b6000602082840312156102f757600080fd5b81516102de816102a956fea2646970667358221220274e52a3b60c7dff1cad0833c349004759648080531c69a484b94b22224cfa1164736f6c63430008090033", + "deployedBytecode": "0x6080604052600436106100385760003560e01c806351720b411461004f57806392eefe9b14610078578063f77c47911461009857610047565b36610047576100456100d0565b005b6100456100d0565b34801561005b57600080fd5b5061006560015481565b6040519081526020015b60405180910390f35b34801561008457600080fd5b506100456100933660046102c1565b6101f1565b3480156100a457600080fd5b506000546100b8906001600160a01b031681565b6040516001600160a01b03909116815260200161006f565b60008054600154604051631c2d8fb360e31b81526001600160a01b039092169163e16c7d98916101069160040190815260200190565b60206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061015691906102e5565b90506001600160a01b0381166101be5760405162461bcd60e51b815260206004820152602260248201527f74617267657420636f6e7472616374206d757374206265207265676973746572604482015261195960f21b60648201526084015b60405180910390fd5b60408051368101825236600082376000803683865af4905081513d810183523d6000823e8180156101ed573d82f35b3d82fd5b6101f961024d565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102a75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c65720000000000000060448201526064016101b5565b565b6001600160a01b03811681146102be57600080fd5b50565b6000602082840312156102d357600080fd5b81356102de816102a9565b9392505050565b6000602082840312156102f757600080fd5b81516102de816102a956fea2646970667358221220274e52a3b60c7dff1cad0833c349004759648080531c69a484b94b22224cfa1164736f6c63430008090033", + "devdoc": { + "details": "Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_controller": "Address of Controller that this contract will be registered with", + "_targetContractId": "contract ID of the target contract" + } + }, + "setController(address)": { + "params": { + "_controller": "Controller contract address" + } + } + }, + "title": "ManagerProxy", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address. Also, sets the contract ID of the target contract that function calls will be executed on." + }, + "setController(address)": { + "notice": "Set controller. Only callable by current controller" + } + }, + "notice": "A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context. The target contract is a Manager contract that is registered with the Controller.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 18792, + "contract": "contracts/ManagerProxy.sol:ManagerProxy", + "label": "controller", + "offset": 0, + "slot": "0", + "type": "t_contract(IController)18767" + }, + { + "astId": 18974, + "contract": "contracts/ManagerProxy.sol:ManagerProxy", + "label": "targetContractId", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "types": { + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IController)18767": { + "encoding": "inplace", + "label": "contract IController", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/arbitrumMainnet/AIServiceRegistryTarget.json b/deployments/arbitrumMainnet/AIServiceRegistryTarget.json new file mode 100644 index 00000000..d8a9bc66 --- /dev/null +++ b/deployments/arbitrumMainnet/AIServiceRegistryTarget.json @@ -0,0 +1,274 @@ +{ + "address": "0x5D31637EB0F442376053d5dEA2347F663C4019DC", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "param", + "type": "string" + } + ], + "name": "ParameterUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "serviceURI", + "type": "string" + } + ], + "name": "ServiceURIUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "SetController", + "type": "event" + }, + { + "inputs": [], + "name": "controller", + "outputs": [ + { + "internalType": "contract IController", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_addr", + "type": "address" + } + ], + "name": "getServiceURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_controller", + "type": "address" + } + ], + "name": "setController", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_serviceURI", + "type": "string" + } + ], + "name": "setServiceURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "targetContractId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x964078f60b1996d3fa746e08afb1db7c89483ae2a21474616b094bedeb4ea830", + "receipt": { + "to": null, + "from": "0xF5282864EC36871c36BF682aFE1C3f180D4f7902", + "contractAddress": "0x5D31637EB0F442376053d5dEA2347F663C4019DC", + "transactionIndex": 1, + "gasUsed": "662675", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x57412148e4abc39146e12b58355a9bf17c3cc012a67d28d0037ac39450f7e866", + "transactionHash": "0x964078f60b1996d3fa746e08afb1db7c89483ae2a21474616b094bedeb4ea830", + "logs": [], + "blockNumber": 202080788, + "cumulativeGasUsed": "662675", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD8E8328501E9645d16Cf49539efC04f734606ee4" + ], + "numDeployments": 1, + "solcInputHash": "e0424c78571e350313a9f65dd4baea4e", + "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"param\",\"type\":\"string\"}],\"name\":\"ParameterUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"serviceURI\",\"type\":\"string\"}],\"name\":\"ServiceURIUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"SetController\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"getServiceURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"setController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_serviceURI\",\"type\":\"string\"}],\"name\":\"setServiceURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetContractId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_controller\":\"Address of a Controller that this contract will be registered with\"}},\"getServiceURI(address)\":{\"params\":{\"_addr\":\"Address for which a service URI endpoint is desired\"}},\"setController(address)\":{\"params\":{\"_controller\":\"Controller contract address\"}},\"setServiceURI(string)\":{\"params\":{\"_serviceURI\":\"Service URI endpoint for the caller\"}}},\"title\":\"ServiceRegistry\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"ServiceRegistry constructor. Only invokes constructor of base Manager contract with provided Controller address\"},\"getServiceURI(address)\":{\"notice\":\"Returns service URI endpoint stored for a given address\"},\"setController(address)\":{\"notice\":\"Set controller. Only callable by current controller\"},\"setServiceURI(string)\":{\"notice\":\"Stores service URI endpoint for the caller that can be used to send requests to the caller off-chain\"}},\"notice\":\"Maintains a registry of service metadata associated with service provider addresses (transcoders/orchestrators)\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ServiceRegistry.sol\":\"ServiceRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/IController.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./zeppelin/Pausable.sol\\\";\\n\\nabstract contract IController is Pausable {\\n event SetContractInfo(bytes32 id, address contractAddress, bytes20 gitCommitHash);\\n\\n function setContractInfo(\\n bytes32 _id,\\n address _contractAddress,\\n bytes20 _gitCommitHash\\n ) external virtual;\\n\\n function updateController(bytes32 _id, address _controller) external virtual;\\n\\n function getContract(bytes32 _id) public view virtual returns (address);\\n}\\n\",\"keccak256\":\"0x34ea30a2b44d0cbec58fc1d703476ff0085b0fdadab0cd65c35c00b8867f7546\",\"license\":\"MIT\"},\"contracts/IManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\ninterface IManager {\\n event SetController(address controller);\\n event ParameterUpdate(string param);\\n\\n function setController(address _controller) external;\\n}\\n\",\"keccak256\":\"0xc179e4cecc593741514237d5194b4aaac6b829789629fa19ed04f572a8530481\",\"license\":\"MIT\"},\"contracts/Manager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./IManager.sol\\\";\\nimport \\\"./IController.sol\\\";\\n\\ncontract Manager is IManager {\\n // Controller that contract is registered with\\n IController public controller;\\n\\n // Check if sender is controller\\n modifier onlyController() {\\n _onlyController();\\n _;\\n }\\n\\n // Check if sender is controller owner\\n modifier onlyControllerOwner() {\\n _onlyControllerOwner();\\n _;\\n }\\n\\n // Check if controller is not paused\\n modifier whenSystemNotPaused() {\\n _whenSystemNotPaused();\\n _;\\n }\\n\\n // Check if controller is paused\\n modifier whenSystemPaused() {\\n _whenSystemPaused();\\n _;\\n }\\n\\n constructor(address _controller) {\\n controller = IController(_controller);\\n }\\n\\n /**\\n * @notice Set controller. Only callable by current controller\\n * @param _controller Controller contract address\\n */\\n function setController(address _controller) external onlyController {\\n controller = IController(_controller);\\n\\n emit SetController(_controller);\\n }\\n\\n function _onlyController() private view {\\n require(msg.sender == address(controller), \\\"caller must be Controller\\\");\\n }\\n\\n function _onlyControllerOwner() private view {\\n require(msg.sender == controller.owner(), \\\"caller must be Controller owner\\\");\\n }\\n\\n function _whenSystemNotPaused() private view {\\n require(!controller.paused(), \\\"system is paused\\\");\\n }\\n\\n function _whenSystemPaused() private view {\\n require(controller.paused(), \\\"system is not paused\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc415e3f42da9f82ddd5953031f3f26aed824368fcc34d3b8a17015bfe80dc109\",\"license\":\"MIT\"},\"contracts/ManagerProxyTarget.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Manager.sol\\\";\\n\\n/**\\n * @title ManagerProxyTarget\\n * @notice The base contract that target contracts used by a proxy contract should inherit from\\n * @dev Both the target contract and the proxy contract (implemented as ManagerProxy) MUST inherit from ManagerProxyTarget in order to guarantee\\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\\n potentially break the delegate proxy upgradeability mechanism\\n */\\nabstract contract ManagerProxyTarget is Manager {\\n // Used to look up target contract address in controller's registry\\n bytes32 public targetContractId;\\n}\\n\",\"keccak256\":\"0x920bcc2def240e06272dc06cbcb9f12976f1698cd4f1020c165af25ee837e553\",\"license\":\"MIT\"},\"contracts/ServiceRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./ManagerProxyTarget.sol\\\";\\n\\n/**\\n * @title ServiceRegistry\\n * @notice Maintains a registry of service metadata associated with service provider addresses (transcoders/orchestrators)\\n */\\ncontract ServiceRegistry is ManagerProxyTarget {\\n // Store service metadata\\n struct Record {\\n string serviceURI; // Service URI endpoint that can be used to send off-chain requests\\n }\\n\\n // Track records for addresses\\n mapping(address => Record) private records;\\n\\n // Event fired when a caller updates its service URI endpoint\\n event ServiceURIUpdate(address indexed addr, string serviceURI);\\n\\n /**\\n * @notice ServiceRegistry constructor. Only invokes constructor of base Manager contract with provided Controller address\\n * @param _controller Address of a Controller that this contract will be registered with\\n */\\n constructor(address _controller) Manager(_controller) {}\\n\\n /**\\n * @notice Stores service URI endpoint for the caller that can be used to send requests to the caller off-chain\\n * @param _serviceURI Service URI endpoint for the caller\\n */\\n function setServiceURI(string calldata _serviceURI) external {\\n records[msg.sender].serviceURI = _serviceURI;\\n\\n emit ServiceURIUpdate(msg.sender, _serviceURI);\\n }\\n\\n /**\\n * @notice Returns service URI endpoint stored for a given address\\n * @param _addr Address for which a service URI endpoint is desired\\n */\\n function getServiceURI(address _addr) public view returns (string memory) {\\n return records[_addr].serviceURI;\\n }\\n}\\n\",\"keccak256\":\"0xca3235eea4230fff83203f07b9be76bf62ee9786dc4768abc351de2c12273563\",\"license\":\"MIT\"},\"contracts/zeppelin/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\ncontract Ownable {\\n address public owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address newOwner) public onlyOwner {\\n require(newOwner != address(0));\\n emit OwnershipTransferred(owner, newOwner);\\n owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x64f114689f2f161c4a4b8fc8442ab914436a33e6021bf17401eaeac73319a419\",\"license\":\"MIT\"},\"contracts/zeppelin/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.9;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @title Pausable\\n * @dev Base contract which allows children to implement an emergency stop mechanism.\\n */\\ncontract Pausable is Ownable {\\n event Pause();\\n event Unpause();\\n\\n bool public paused;\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n */\\n modifier whenNotPaused() {\\n require(!paused);\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n */\\n modifier whenPaused() {\\n require(paused);\\n _;\\n }\\n\\n /**\\n * @dev called by the owner to pause, triggers stopped state\\n */\\n function pause() public onlyOwner whenNotPaused {\\n paused = true;\\n emit Pause();\\n }\\n\\n /**\\n * @dev called by the owner to unpause, returns to normal state\\n */\\n function unpause() public onlyOwner whenPaused {\\n paused = false;\\n emit Unpause();\\n }\\n}\\n\",\"keccak256\":\"0xe9635fcac46c22547a08f6977a8c75e7341411f1201f60bdd4c79c26e6c286ef\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161057c38038061057c83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6104e9806100936000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063214c2a4b1461005c57806351720b41146100855780635f11301b1461009c57806392eefe9b146100b1578063f77c4791146100c4575b600080fd5b61006f61006a366004610352565b6100ef565b60405161007c9190610382565b60405180910390f35b61008e60015481565b60405190815260200161007c565b6100af6100aa3660046103d7565b61019b565b005b6100af6100bf366004610352565b6101fd565b6000546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161007c565b6001600160a01b038116600090815260026020526040902080546060919061011690610449565b80601f016020809104026020016040519081016040528092919081815260200182805461014290610449565b801561018f5780601f106101645761010080835404028352916020019161018f565b820191906000526020600020905b81548152906001019060200180831161017257829003601f168201915b50505050509050919050565b3360009081526002602052604090206101b59083836102b9565b50336001600160a01b03167ffbb63068732c85741c9f8e61caffaabe038d577bfafd2d2dcc0e352a4f653a4c83836040516101f1929190610484565b60405180910390a25050565b610205610259565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102b75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015260640160405180910390fd5b565b8280546102c590610449565b90600052602060002090601f0160209004810192826102e7576000855561032d565b82601f106103005782800160ff1982351617855561032d565b8280016001018555821561032d579182015b8281111561032d578235825591602001919060010190610312565b5061033992915061033d565b5090565b5b80821115610339576000815560010161033e565b60006020828403121561036457600080fd5b81356001600160a01b038116811461037b57600080fd5b9392505050565b600060208083528351808285015260005b818110156103af57858101830151858201604001528201610393565b818111156103c1576000604083870101525b50601f01601f1916929092016040019392505050565b600080602083850312156103ea57600080fd5b823567ffffffffffffffff8082111561040257600080fd5b818501915085601f83011261041657600080fd5b81358181111561042557600080fd5b86602082850101111561043757600080fd5b60209290920196919550909350505050565b600181811c9082168061045d57607f821691505b6020821081141561047e57634e487b7160e01b600052602260045260246000fd5b50919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220072fab04e9b0eb88e7ce73c7ea0dd0e46030826f89b48af04a185d7ac13df8de64736f6c63430008090033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063214c2a4b1461005c57806351720b41146100855780635f11301b1461009c57806392eefe9b146100b1578063f77c4791146100c4575b600080fd5b61006f61006a366004610352565b6100ef565b60405161007c9190610382565b60405180910390f35b61008e60015481565b60405190815260200161007c565b6100af6100aa3660046103d7565b61019b565b005b6100af6100bf366004610352565b6101fd565b6000546100d7906001600160a01b031681565b6040516001600160a01b03909116815260200161007c565b6001600160a01b038116600090815260026020526040902080546060919061011690610449565b80601f016020809104026020016040519081016040528092919081815260200182805461014290610449565b801561018f5780601f106101645761010080835404028352916020019161018f565b820191906000526020600020905b81548152906001019060200180831161017257829003601f168201915b50505050509050919050565b3360009081526002602052604090206101b59083836102b9565b50336001600160a01b03167ffbb63068732c85741c9f8e61caffaabe038d577bfafd2d2dcc0e352a4f653a4c83836040516101f1929190610484565b60405180910390a25050565b610205610259565b600080546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709060200160405180910390a150565b6000546001600160a01b031633146102b75760405162461bcd60e51b815260206004820152601960248201527f63616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015260640160405180910390fd5b565b8280546102c590610449565b90600052602060002090601f0160209004810192826102e7576000855561032d565b82601f106103005782800160ff1982351617855561032d565b8280016001018555821561032d579182015b8281111561032d578235825591602001919060010190610312565b5061033992915061033d565b5090565b5b80821115610339576000815560010161033e565b60006020828403121561036457600080fd5b81356001600160a01b038116811461037b57600080fd5b9392505050565b600060208083528351808285015260005b818110156103af57858101830151858201604001528201610393565b818111156103c1576000604083870101525b50601f01601f1916929092016040019392505050565b600080602083850312156103ea57600080fd5b823567ffffffffffffffff8082111561040257600080fd5b818501915085601f83011261041657600080fd5b81358181111561042557600080fd5b86602082850101111561043757600080fd5b60209290920196919550909350505050565b600181811c9082168061045d57607f821691505b6020821081141561047e57634e487b7160e01b600052602260045260246000fd5b50919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f1916010191905056fea2646970667358221220072fab04e9b0eb88e7ce73c7ea0dd0e46030826f89b48af04a185d7ac13df8de64736f6c63430008090033", + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_controller": "Address of a Controller that this contract will be registered with" + } + }, + "getServiceURI(address)": { + "params": { + "_addr": "Address for which a service URI endpoint is desired" + } + }, + "setController(address)": { + "params": { + "_controller": "Controller contract address" + } + }, + "setServiceURI(string)": { + "params": { + "_serviceURI": "Service URI endpoint for the caller" + } + } + }, + "title": "ServiceRegistry", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "ServiceRegistry constructor. Only invokes constructor of base Manager contract with provided Controller address" + }, + "getServiceURI(address)": { + "notice": "Returns service URI endpoint stored for a given address" + }, + "setController(address)": { + "notice": "Set controller. Only callable by current controller" + }, + "setServiceURI(string)": { + "notice": "Stores service URI endpoint for the caller that can be used to send requests to the caller off-chain" + } + }, + "notice": "Maintains a registry of service metadata associated with service provider addresses (transcoders/orchestrators)", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 18792, + "contract": "contracts/ServiceRegistry.sol:ServiceRegistry", + "label": "controller", + "offset": 0, + "slot": "0", + "type": "t_contract(IController)18767" + }, + { + "astId": 18974, + "contract": "contracts/ServiceRegistry.sol:ServiceRegistry", + "label": "targetContractId", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 18989, + "contract": "contracts/ServiceRegistry.sol:ServiceRegistry", + "label": "records", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_struct(Record)18984_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IController)18767": { + "encoding": "inplace", + "label": "contract IController", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_struct(Record)18984_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct ServiceRegistry.Record)", + "numberOfBytes": "32", + "value": "t_struct(Record)18984_storage" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Record)18984_storage": { + "encoding": "inplace", + "label": "struct ServiceRegistry.Record", + "members": [ + { + "astId": 18983, + "contract": "contracts/ServiceRegistry.sol:ServiceRegistry", + "label": "serviceURI", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + } + ], + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/arbitrumMainnet/solcInputs/e0424c78571e350313a9f65dd4baea4e.json b/deployments/arbitrumMainnet/solcInputs/e0424c78571e350313a9f65dd4baea4e.json new file mode 100644 index 00000000..5e68a3d0 --- /dev/null +++ b/deployments/arbitrumMainnet/solcInputs/e0424c78571e350313a9f65dd4baea4e.json @@ -0,0 +1,494 @@ +{ + "language": "Solidity", + "sources": { + "contracts/bonding/BondingManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../ManagerProxyTarget.sol\";\nimport \"./IBondingManager.sol\";\nimport \"../libraries/SortedDoublyLL.sol\";\nimport \"../libraries/MathUtils.sol\";\nimport \"../libraries/PreciseMathUtils.sol\";\nimport \"./libraries/EarningsPool.sol\";\nimport \"./libraries/EarningsPoolLIP36.sol\";\nimport \"../token/ILivepeerToken.sol\";\nimport \"../token/IMinter.sol\";\nimport \"../rounds/IRoundsManager.sol\";\nimport \"../snapshots/IMerkleSnapshot.sol\";\nimport \"./IBondingVotes.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n/**\n * @title BondingManager\n * @notice Manages bonding, transcoder and rewards/fee accounting related operations of the Livepeer protocol\n */\ncontract BondingManager is ManagerProxyTarget, IBondingManager {\n using SafeMath for uint256;\n using SortedDoublyLL for SortedDoublyLL.Data;\n using EarningsPool for EarningsPool.Data;\n using EarningsPoolLIP36 for EarningsPool.Data;\n\n // Constants\n // Occurances are replaced at compile time\n // and computed to a single value if possible by the optimizer\n uint256 constant MAX_FUTURE_ROUND = 2**256 - 1;\n\n // Time between unbonding and possible withdrawl in rounds\n uint64 public unbondingPeriod;\n\n // Represents a transcoder's current state\n struct Transcoder {\n uint256 lastRewardRound; // Last round that the transcoder called reward\n uint256 rewardCut; // % of reward paid to transcoder by a delegator\n uint256 feeShare; // % of fees paid to delegators by transcoder\n mapping(uint256 => EarningsPool.Data) earningsPoolPerRound; // Mapping of round => earnings pool for the round\n uint256 lastActiveStakeUpdateRound; // Round for which the stake was last updated while the transcoder is active\n uint256 activationRound; // Round in which the transcoder became active - if inactive will be 0 or <=deactivationRound\n uint256 deactivationRound; // Round in which the transcoder will become inactive\n uint256 activeCumulativeRewards; // The transcoder's cumulative rewards that are active in the current round\n uint256 cumulativeRewards; // The transcoder's cumulative rewards (earned via the its active staked rewards and its reward cut).\n uint256 cumulativeFees; // The transcoder's cumulative fees (earned via the its active staked rewards and its fee share)\n uint256 lastFeeRound; // Latest round in which the transcoder received fees\n }\n\n // The various states a transcoder can be in\n enum TranscoderStatus {\n NotRegistered,\n Registered\n }\n\n // Represents a delegator's current state\n struct Delegator {\n uint256 bondedAmount; // The amount of bonded tokens\n uint256 fees; // The amount of fees collected\n address delegateAddress; // The address delegated to\n uint256 delegatedAmount; // The amount of tokens delegated to the delegator\n uint256 startRound; // The round the delegator transitions to bonded phase and is delegated to someone\n uint256 lastClaimRound; // The last round during which the delegator claimed its earnings\n uint256 nextUnbondingLockId; // ID for the next unbonding lock created\n mapping(uint256 => UnbondingLock) unbondingLocks; // Mapping of unbonding lock ID => unbonding lock\n }\n\n // The various states a delegator can be in\n enum DelegatorStatus {\n Pending,\n Bonded,\n Unbonded\n }\n\n // Represents an amount of tokens that are being unbonded\n struct UnbondingLock {\n uint256 amount; // Amount of tokens being unbonded\n uint256 withdrawRound; // Round at which unbonding period is over and tokens can be withdrawn\n }\n\n // Keep track of the known transcoders and delegators\n mapping(address => Delegator) private delegators;\n mapping(address => Transcoder) private transcoders;\n\n // The total active stake (sum of the stake of active set members) for the current round\n uint256 public currentRoundTotalActiveStake;\n // The total active stake (sum of the stake of active set members) for the next round\n uint256 public nextRoundTotalActiveStake;\n\n // The transcoder pool is used to keep track of the transcoders that are eligible for activation.\n // The pool keeps track of the pending active set in round N and the start of round N + 1 transcoders\n // in the pool are locked into the active set for round N + 1\n SortedDoublyLL.Data private transcoderPool;\n\n // The % of newly minted rewards to be routed to the treasury. Represented as a PreciseMathUtils percPoint value.\n uint256 public treasuryRewardCutRate;\n // The value for `treasuryRewardCutRate` to be set on the next round initialization.\n uint256 public nextRoundTreasuryRewardCutRate;\n\n // If the balance of the treasury in LPT is above this value, automatic treasury contributions will halt.\n uint256 public treasuryBalanceCeiling;\n\n // Check if sender is TicketBroker\n modifier onlyTicketBroker() {\n _onlyTicketBroker();\n _;\n }\n\n // Check if sender is RoundsManager\n modifier onlyRoundsManager() {\n _onlyRoundsManager();\n _;\n }\n\n // Check if sender is Verifier\n modifier onlyVerifier() {\n _onlyVerifier();\n _;\n }\n\n // Check if current round is initialized\n modifier currentRoundInitialized() {\n _currentRoundInitialized();\n _;\n }\n\n // Automatically claim earnings from lastClaimRound through the current round\n modifier autoClaimEarnings(address _delegator) {\n _autoClaimEarnings(_delegator);\n _;\n }\n\n modifier autoCheckpoint(address _account) {\n _;\n _checkpointBondingState(_account, delegators[_account], transcoders[_account]);\n }\n\n /**\n * @notice BondingManager constructor. Only invokes constructor of base Manager contract with provided Controller address\n * @dev This constructor will not initialize any state variables besides `controller`. The following setter functions\n * should be used to initialize state variables post-deployment:\n * - setUnbondingPeriod()\n * - setNumActiveTranscoders()\n * @param _controller Address of Controller that this contract will be registered with\n */\n constructor(address _controller) Manager(_controller) {}\n\n /**\n * @notice Set unbonding period. Only callable by Controller owner\n * @param _unbondingPeriod Rounds between unbonding and possible withdrawal\n */\n function setUnbondingPeriod(uint64 _unbondingPeriod) external onlyControllerOwner {\n unbondingPeriod = _unbondingPeriod;\n\n emit ParameterUpdate(\"unbondingPeriod\");\n }\n\n /**\n * @notice Set treasury reward cut rate. Only callable by Controller owner. Notice that the change will only be\n * effective on the next round.\n * @param _cutRate Percentage of newly minted rewards to route to the treasury. Must be a valid PreciseMathUtils\n * percentage (<100% specified with 27-digits precision).\n */\n function setTreasuryRewardCutRate(uint256 _cutRate) external onlyControllerOwner {\n _setTreasuryRewardCutRate(_cutRate);\n }\n\n /**\n * @notice Set treasury balance ceiling. Only callable by Controller owner\n * @param _ceiling Balance at which treasury reward contributions should halt. Specified in LPT fractional units\n * (18-digit precision).\n */\n function setTreasuryBalanceCeiling(uint256 _ceiling) external onlyControllerOwner {\n treasuryBalanceCeiling = _ceiling;\n\n emit ParameterUpdate(\"treasuryBalanceCeiling\");\n }\n\n /**\n * @notice Set maximum number of active transcoders. Only callable by Controller owner\n * @param _numActiveTranscoders Number of active transcoders\n */\n function setNumActiveTranscoders(uint256 _numActiveTranscoders) external onlyControllerOwner {\n transcoderPool.setMaxSize(_numActiveTranscoders);\n\n emit ParameterUpdate(\"numActiveTranscoders\");\n }\n\n /**\n * @notice Sets commission rates as a transcoder and if the caller is not in the transcoder pool tries to add it\n * @dev Percentages are represented as numerators of fractions over MathUtils.PERC_DIVISOR\n * @param _rewardCut % of reward paid to transcoder by a delegator\n * @param _feeShare % of fees paid to delegators by a transcoder\n */\n function transcoder(uint256 _rewardCut, uint256 _feeShare) external {\n transcoderWithHint(_rewardCut, _feeShare, address(0), address(0));\n }\n\n /**\n * @notice Delegate stake towards a specific address\n * @param _amount The amount of tokens to stake\n * @param _to The address of the transcoder to stake towards\n */\n function bond(uint256 _amount, address _to) external {\n bondWithHint(_amount, _to, address(0), address(0), address(0), address(0));\n }\n\n /**\n * @notice Unbond an amount of the delegator's bonded stake\n * @param _amount Amount of tokens to unbond\n */\n function unbond(uint256 _amount) external {\n unbondWithHint(_amount, address(0), address(0));\n }\n\n /**\n * @notice Rebond tokens for an unbonding lock to a delegator's current delegate while a delegator is in the Bonded or Pending status\n * @param _unbondingLockId ID of unbonding lock to rebond with\n */\n function rebond(uint256 _unbondingLockId) external {\n rebondWithHint(_unbondingLockId, address(0), address(0));\n }\n\n /**\n * @notice Rebond tokens for an unbonding lock to a delegate while a delegator is in the Unbonded status\n * @param _to Address of delegate\n * @param _unbondingLockId ID of unbonding lock to rebond with\n */\n function rebondFromUnbonded(address _to, uint256 _unbondingLockId) external {\n rebondFromUnbondedWithHint(_to, _unbondingLockId, address(0), address(0));\n }\n\n /**\n * @notice Checkpoints the bonding state for a given account.\n * @dev This is to allow checkpointing an account that has an inconsistent checkpoint with its current state.\n * @param _account The account to make the checkpoint for\n */\n function checkpointBondingState(address _account) external {\n _checkpointBondingState(_account, delegators[_account], transcoders[_account]);\n }\n\n /**\n * @notice Withdraws tokens for an unbonding lock that has existed through an unbonding period\n * @param _unbondingLockId ID of unbonding lock to withdraw with\n */\n function withdrawStake(uint256 _unbondingLockId) external whenSystemNotPaused currentRoundInitialized {\n Delegator storage del = delegators[msg.sender];\n UnbondingLock storage lock = del.unbondingLocks[_unbondingLockId];\n\n require(isValidUnbondingLock(msg.sender, _unbondingLockId), \"invalid unbonding lock ID\");\n require(\n lock.withdrawRound <= roundsManager().currentRound(),\n \"withdraw round must be before or equal to the current round\"\n );\n\n uint256 amount = lock.amount;\n uint256 withdrawRound = lock.withdrawRound;\n // Delete unbonding lock\n delete del.unbondingLocks[_unbondingLockId];\n\n // Tell Minter to transfer stake (LPT) to the delegator\n minter().trustedTransferTokens(msg.sender, amount);\n\n emit WithdrawStake(msg.sender, _unbondingLockId, amount, withdrawRound);\n }\n\n /**\n * @notice Withdraws fees to the caller\n */\n function withdrawFees(address payable _recipient, uint256 _amount)\n external\n whenSystemNotPaused\n currentRoundInitialized\n autoClaimEarnings(msg.sender)\n autoCheckpoint(msg.sender)\n {\n require(_recipient != address(0), \"invalid recipient\");\n uint256 fees = delegators[msg.sender].fees;\n require(fees >= _amount, \"insufficient fees to withdraw\");\n delegators[msg.sender].fees = fees.sub(_amount);\n\n // Tell Minter to transfer fees (ETH) to the address\n minter().trustedWithdrawETH(_recipient, _amount);\n\n emit WithdrawFees(msg.sender, _recipient, _amount);\n }\n\n /**\n * @notice Mint token rewards for an active transcoder and its delegators\n */\n function reward() external {\n rewardWithHint(address(0), address(0));\n }\n\n /**\n * @notice Update transcoder's fee pool. Only callable by the TicketBroker\n * @param _transcoder Transcoder address\n * @param _fees Fees to be added to the fee pool\n */\n function updateTranscoderWithFees(\n address _transcoder,\n uint256 _fees,\n uint256 _round\n ) external whenSystemNotPaused onlyTicketBroker {\n // Silence unused param compiler warning\n _round;\n\n require(isRegisteredTranscoder(_transcoder), \"transcoder must be registered\");\n\n uint256 currentRound = roundsManager().currentRound();\n\n Transcoder storage t = transcoders[_transcoder];\n\n uint256 lastRewardRound = t.lastRewardRound;\n uint256 activeCumulativeRewards = t.activeCumulativeRewards;\n\n // LIP-36: Add fees for the current round instead of '_round'\n // https://github.com/livepeer/LIPs/issues/35#issuecomment-673659199\n EarningsPool.Data storage earningsPool = t.earningsPoolPerRound[currentRound];\n EarningsPool.Data memory prevEarningsPool = latestCumulativeFactorsPool(t, currentRound.sub(1));\n\n // if transcoder hasn't called 'reward()' for '_round' its 'transcoderFeeShare', 'transcoderRewardCut' and 'totalStake'\n // on the 'EarningsPool' for '_round' would not be initialized and the fee distribution wouldn't happen as expected\n // for cumulative fee calculation this would result in division by zero.\n if (currentRound > lastRewardRound) {\n earningsPool.setCommission(t.rewardCut, t.feeShare);\n\n uint256 lastUpdateRound = t.lastActiveStakeUpdateRound;\n if (lastUpdateRound < currentRound) {\n earningsPool.setStake(t.earningsPoolPerRound[lastUpdateRound].totalStake);\n }\n\n // If reward() has not been called yet in the current round, then the transcoder's activeCumulativeRewards has not\n // yet been set in for the round. When the transcoder calls reward() its activeCumulativeRewards will be set to its\n // current cumulativeRewards. So, we can just use the transcoder's cumulativeRewards here because this will become\n // the transcoder's activeCumulativeRewards if it calls reward() later on in the current round\n activeCumulativeRewards = t.cumulativeRewards;\n }\n\n uint256 totalStake = earningsPool.totalStake;\n if (prevEarningsPool.cumulativeRewardFactor == 0 && lastRewardRound == currentRound) {\n // if transcoder called reward for 'currentRound' but not for 'currentRound - 1' (missed reward call)\n // retroactively calculate what its cumulativeRewardFactor would have been for 'currentRound - 1' (cfr. previous lastRewardRound for transcoder)\n // based on rewards for currentRound\n IMinter mtr = minter();\n uint256 rewards = PreciseMathUtils.percOf(\n mtr.currentMintableTokens().add(mtr.currentMintedTokens()),\n totalStake,\n currentRoundTotalActiveStake\n );\n\n // deduct what were the treasury rewards\n uint256 treasuryRewards = PreciseMathUtils.percOf(rewards, treasuryRewardCutRate);\n rewards = rewards.sub(treasuryRewards);\n\n uint256 transcoderCommissionRewards = MathUtils.percOf(rewards, earningsPool.transcoderRewardCut);\n uint256 delegatorsRewards = rewards.sub(transcoderCommissionRewards);\n\n prevEarningsPool.cumulativeRewardFactor = PreciseMathUtils.percOf(\n earningsPool.cumulativeRewardFactor,\n totalStake,\n delegatorsRewards.add(totalStake)\n );\n }\n\n uint256 delegatorsFees = MathUtils.percOf(_fees, earningsPool.transcoderFeeShare);\n uint256 transcoderCommissionFees = _fees.sub(delegatorsFees);\n // Calculate the fees earned by the transcoder's earned rewards\n uint256 transcoderRewardStakeFees = PreciseMathUtils.percOf(\n delegatorsFees,\n activeCumulativeRewards,\n totalStake\n );\n // Track fees earned by the transcoder based on its earned rewards and feeShare\n t.cumulativeFees = t.cumulativeFees.add(transcoderRewardStakeFees).add(transcoderCommissionFees);\n // Update cumulative fee factor with new fees\n // The cumulativeFeeFactor is used to calculate fees for all delegators including the transcoder (self-delegated)\n // Note that delegatorsFees includes transcoderRewardStakeFees, but no delegator will claim that amount using\n // the earnings claiming algorithm and instead that amount is accounted for in the transcoder's cumulativeFees field\n earningsPool.updateCumulativeFeeFactor(prevEarningsPool, delegatorsFees);\n\n t.lastFeeRound = currentRound;\n }\n\n /**\n * @notice Slash a transcoder. Only callable by the Verifier.\n * @dev This function is not currently used today as the Verifier role is set to the null address (0x000...). It\n * still remains a key part of the protocol's security model and could be enabled via governance by configuring the\n * Verifier role. The function would also require compatibility updates to align with the latest BondingManager\n * logical accounting, so the protocol governance would make sure to only enable it after such updates have been\n * made. Until then, this function and its side-effects are out of scope of any audits made in this code.\n * @param _transcoder Transcoder address\n * @param _finder Finder that proved a transcoder violated a slashing condition. Null address if there is no finder\n * @param _slashAmount Percentage of transcoder bond to be slashed\n * @param _finderFee Percentage of penalty awarded to finder. Zero if there is no finder\n */\n function slashTranscoder(\n address _transcoder,\n address _finder,\n uint256 _slashAmount,\n uint256 _finderFee\n ) external whenSystemNotPaused onlyVerifier autoClaimEarnings(_transcoder) autoCheckpoint(_transcoder) {\n Delegator storage del = delegators[_transcoder];\n\n if (del.bondedAmount > 0) {\n uint256 penalty = MathUtils.percOf(delegators[_transcoder].bondedAmount, _slashAmount);\n\n // If active transcoder, resign it\n if (transcoderPool.contains(_transcoder)) {\n resignTranscoder(_transcoder);\n }\n\n // Decrease bonded stake\n del.bondedAmount = del.bondedAmount.sub(penalty);\n\n // If still bonded decrease delegate's delegated amount\n if (delegatorStatus(_transcoder) == DelegatorStatus.Bonded) {\n delegators[del.delegateAddress].delegatedAmount = delegators[del.delegateAddress].delegatedAmount.sub(\n penalty\n );\n }\n\n // Account for penalty\n uint256 burnAmount = penalty;\n\n // Award finder fee if there is a finder address\n if (_finder != address(0)) {\n uint256 finderAmount = MathUtils.percOf(penalty, _finderFee);\n minter().trustedTransferTokens(_finder, finderAmount);\n\n // Minter burns the slashed funds - finder reward\n minter().trustedBurnTokens(burnAmount.sub(finderAmount));\n\n emit TranscoderSlashed(_transcoder, _finder, penalty, finderAmount);\n } else {\n // Minter burns the slashed funds\n minter().trustedBurnTokens(burnAmount);\n\n emit TranscoderSlashed(_transcoder, address(0), penalty, 0);\n }\n } else {\n emit TranscoderSlashed(_transcoder, _finder, 0, 0);\n }\n }\n\n /**\n * @notice Claim token pools shares for a delegator from its lastClaimRound through the end round\n * @param _endRound Unused, but used to represented the last round for which to claim token pools shares for a\n * delegator. Currently, the earnings are always claimed until the current round instead.\n */\n function claimEarnings(uint256 _endRound)\n external\n whenSystemNotPaused\n currentRoundInitialized\n autoCheckpoint(msg.sender)\n {\n // Silence unused param compiler warning\n _endRound;\n\n _autoClaimEarnings(msg.sender);\n }\n\n /**\n * @notice Called during round initialization to set the total active stake for the round. Only callable by the RoundsManager\n */\n function setCurrentRoundTotalActiveStake() external onlyRoundsManager {\n currentRoundTotalActiveStake = nextRoundTotalActiveStake;\n\n if (nextRoundTreasuryRewardCutRate != treasuryRewardCutRate) {\n treasuryRewardCutRate = nextRoundTreasuryRewardCutRate;\n // The treasury cut rate changes in a delayed fashion so we want to emit the parameter update event here\n emit ParameterUpdate(\"treasuryRewardCutRate\");\n }\n\n bondingVotes().checkpointTotalActiveStake(currentRoundTotalActiveStake, roundsManager().currentRound());\n }\n\n /**\n * @notice Sets commission rates as a transcoder and if the caller is not in the transcoder pool tries to add it using an optional list hint\n * @dev Percentages are represented as numerators of fractions over MathUtils.PERC_DIVISOR. If the caller is going to be added to the pool, the\n * caller can provide an optional hint for the insertion position in the pool via the `_newPosPrev` and `_newPosNext` params. A linear search will\n * be executed starting at the hint to find the correct position - in the best case, the hint is the correct position so no search is executed.\n * See SortedDoublyLL.sol for details on list hints\n * @param _rewardCut % of reward paid to transcoder by a delegator\n * @param _feeShare % of fees paid to delegators by a transcoder\n * @param _newPosPrev Address of previous transcoder in pool if the caller joins the pool\n * @param _newPosNext Address of next transcoder in pool if the caller joins the pool\n */\n function transcoderWithHint(\n uint256 _rewardCut,\n uint256 _feeShare,\n address _newPosPrev,\n address _newPosNext\n ) public whenSystemNotPaused currentRoundInitialized {\n require(!roundsManager().currentRoundLocked(), \"can't update transcoder params, current round is locked\");\n require(MathUtils.validPerc(_rewardCut), \"invalid rewardCut percentage\");\n require(MathUtils.validPerc(_feeShare), \"invalid feeShare percentage\");\n require(isRegisteredTranscoder(msg.sender), \"transcoder must be registered\");\n\n Transcoder storage t = transcoders[msg.sender];\n uint256 currentRound = roundsManager().currentRound();\n\n require(\n !isActiveTranscoder(msg.sender) || t.lastRewardRound == currentRound,\n \"caller can't be active or must have already called reward for the current round\"\n );\n\n t.rewardCut = _rewardCut;\n t.feeShare = _feeShare;\n\n if (!transcoderPool.contains(msg.sender)) {\n tryToJoinActiveSet(\n msg.sender,\n delegators[msg.sender].delegatedAmount,\n currentRound.add(1),\n _newPosPrev,\n _newPosNext\n );\n }\n\n emit TranscoderUpdate(msg.sender, _rewardCut, _feeShare);\n }\n\n /**\n * @notice Delegates stake \"on behalf of\" another address towards a specific address\n * and updates the transcoder pool using optional list hints if needed\n * @dev If the caller is decreasing the stake of its old delegate in the transcoder pool, the caller can provide an optional hint\n * for the insertion position of the old delegate via the `_oldDelegateNewPosPrev` and `_oldDelegateNewPosNext` params.\n * If the caller is delegating to a delegate that is in the transcoder pool, the caller can provide an optional hint for the\n * insertion position of the delegate via the `_currDelegateNewPosPrev` and `_currDelegateNewPosNext` params.\n * In both cases, a linear search will be executed starting at the hint to find the correct position. In the best case, the hint\n * is the correct position so no search is executed. See SortedDoublyLL.sol for details on list hints\n * @param _amount The amount of tokens to stake.\n * @param _owner The address of the owner of the bond\n * @param _to The address of the transcoder to stake towards\n * @param _oldDelegateNewPosPrev The address of the previous transcoder in the pool for the old delegate\n * @param _oldDelegateNewPosNext The address of the next transcoder in the pool for the old delegate\n * @param _currDelegateNewPosPrev The address of the previous transcoder in the pool for the current delegate\n * @param _currDelegateNewPosNext The address of the next transcoder in the pool for the current delegate\n */\n function bondForWithHint(\n uint256 _amount,\n address _owner,\n address _to,\n address _oldDelegateNewPosPrev,\n address _oldDelegateNewPosNext,\n address _currDelegateNewPosPrev,\n address _currDelegateNewPosNext\n ) public whenSystemNotPaused currentRoundInitialized {\n // the `autoClaimEarnings` modifier has been replaced with its internal function as a `Stack too deep` error work-around\n _authorizeClaimEarnings(_owner);\n _autoClaimEarnings(_owner);\n Delegator storage del = delegators[_owner];\n\n uint256 currentRound = roundsManager().currentRound();\n // Amount to delegate\n uint256 delegationAmount = _amount;\n // Current delegate\n address currentDelegate = del.delegateAddress;\n // Current bonded amount\n uint256 currentBondedAmount = del.bondedAmount;\n\n // Requirements for a third party caller that is not the L2Migrator\n if (msg.sender != _owner && msg.sender != l2Migrator()) {\n // Does not bond for the zero address\n require(_owner != address(0), \"INVALID_DELEGATOR\");\n\n if (delegatorStatus(_owner) == DelegatorStatus.Unbonded) {\n // Does not trigger self-delegation\n require(_to != _owner, \"INVALID_DELEGATE\");\n } else {\n // Does not change the delegate if it is already non-null\n require(currentDelegate == _to, \"INVALID_DELEGATE_CHANGE\");\n }\n }\n\n if (delegatorStatus(_owner) == DelegatorStatus.Unbonded) {\n // New delegate\n // Set start round\n // Don't set start round if delegator is in pending state because the start round would not change\n del.startRound = currentRound.add(1);\n // Unbonded state = no existing delegate and no bonded stake\n // Thus, delegation amount = provided amount\n } else if (currentBondedAmount > 0 && currentDelegate != _to) {\n // A registered transcoder cannot delegate its bonded stake toward another address\n // because it can only be delegated toward itself\n // In the future, if delegation towards another registered transcoder as an already\n // registered transcoder becomes useful (i.e. for transitive delegation), this restriction\n // could be removed\n require(!isRegisteredTranscoder(_owner), \"registered transcoders can't delegate towards other addresses\");\n // Changing delegate\n // Set start round\n del.startRound = currentRound.add(1);\n // Update amount to delegate with previous delegation amount\n delegationAmount = delegationAmount.add(currentBondedAmount);\n\n decreaseTotalStake(currentDelegate, currentBondedAmount, _oldDelegateNewPosPrev, _oldDelegateNewPosNext);\n // no need to prevent double checkpointing since _owner is not a transcoder (i.e. currentDelegate != _owner)\n _checkpointBondingState(currentDelegate, delegators[currentDelegate], transcoders[currentDelegate]);\n }\n\n ensureInitializedCumulativeFactorsPool(_to, currentRound);\n\n // cannot delegate to someone without having bonded stake\n require(delegationAmount > 0, \"delegation amount must be greater than 0\");\n // Update delegate\n del.delegateAddress = _to;\n // Update bonded amount\n del.bondedAmount = currentBondedAmount.add(_amount);\n\n increaseTotalStake(_to, delegationAmount, _currDelegateNewPosPrev, _currDelegateNewPosNext);\n if (_to != _owner) {\n // Avoid double checkpointing of the transcoder if it's a self-bond\n _checkpointBondingState(_to, delegators[_to], transcoders[_to]);\n }\n\n if (_amount > 0) {\n // Transfer the LPT to the Minter\n livepeerToken().transferFrom(msg.sender, address(minter()), _amount);\n }\n\n emit Bond(_to, currentDelegate, _owner, _amount, del.bondedAmount);\n\n // the `autoCheckpoint` modifier has been replaced with its internal function as a `Stack too deep` error work-around\n _checkpointBondingState(_owner, del, transcoders[_owner]);\n }\n\n /**\n * @notice Delegates stake towards a specific address and updates the transcoder pool using optional list hints if needed\n * @dev If the caller is decreasing the stake of its old delegate in the transcoder pool, the caller can provide an optional hint\n * for the insertion position of the old delegate via the `_oldDelegateNewPosPrev` and `_oldDelegateNewPosNext` params.\n * If the caller is delegating to a delegate that is in the transcoder pool, the caller can provide an optional hint for the\n * insertion position of the delegate via the `_currDelegateNewPosPrev` and `_currDelegateNewPosNext` params.\n * In both cases, a linear search will be executed starting at the hint to find the correct position. In the best case, the hint\n * is the correct position so no search is executed. See SortedDoublyLL.sol for details on list hints\n * @param _amount The amount of tokens to stake.\n * @param _to The address of the transcoder to stake towards\n * @param _oldDelegateNewPosPrev The address of the previous transcoder in the pool for the old delegate\n * @param _oldDelegateNewPosNext The address of the next transcoder in the pool for the old delegate\n * @param _currDelegateNewPosPrev The address of the previous transcoder in the pool for the current delegate\n * @param _currDelegateNewPosNext The address of the next transcoder in the pool for the current delegate\n */\n function bondWithHint(\n uint256 _amount,\n address _to,\n address _oldDelegateNewPosPrev,\n address _oldDelegateNewPosNext,\n address _currDelegateNewPosPrev,\n address _currDelegateNewPosNext\n ) public {\n bondForWithHint(\n _amount,\n msg.sender,\n _to,\n _oldDelegateNewPosPrev,\n _oldDelegateNewPosNext,\n _currDelegateNewPosPrev,\n _currDelegateNewPosNext\n );\n }\n\n /**\n * @notice Transfers ownership of a bond to a new delegator using optional hints if needed\n *\n * If the receiver is already bonded to a different delegate than the bond owner then the stake goes\n * to the receiver's delegate otherwise the receiver's delegate is set as the owner's delegate\n *\n * @dev If the original delegate is in the transcoder pool, the caller can provide an optional hint for the\n * insertion position of the delegate via the `_oldDelegateNewPosPrev` and `_oldDelegateNewPosNext` params.\n * If the target delegate is in the transcoder pool, the caller can provide an optional hint for the\n * insertion position of the delegate via the `_newDelegateNewPosPrev` and `_newDelegateNewPosNext` params.\n *\n * In both cases, a linear search will be executed starting at the hint to find the correct position. In the best case, the hint\n * is the correct position so no search is executed. See SortedDoublyLL.sol for details on list hints\n * @param _delegator Receiver of the bond\n * @param _amount Portion of the bond to transfer to receiver\n * @param _oldDelegateNewPosPrev Address of previous transcoder in pool if the delegate remains in the pool\n * @param _oldDelegateNewPosNext Address of next transcoder in pool if the delegate remains in the pool\n * @param _newDelegateNewPosPrev Address of previous transcoder in pool if the delegate is in the pool\n * @param _newDelegateNewPosNext Address of next transcoder in pool if the delegate is in the pool\n */\n function transferBond(\n address _delegator,\n uint256 _amount,\n address _oldDelegateNewPosPrev,\n address _oldDelegateNewPosNext,\n address _newDelegateNewPosPrev,\n address _newDelegateNewPosNext\n ) public whenSystemNotPaused currentRoundInitialized {\n // the `autoClaimEarnings` modifier has been replaced with its internal function as a `Stack too deep` error work-around\n _authorizeClaimEarnings(_delegator);\n _autoClaimEarnings(msg.sender);\n Delegator storage oldDel = delegators[msg.sender];\n Delegator storage newDel = delegators[_delegator];\n // Cache delegate address of caller before unbondWithHint because\n // if unbondWithHint is for a full unbond the caller's delegate address will be set to null\n address oldDelDelegate = oldDel.delegateAddress;\n\n unbondWithHint(_amount, _oldDelegateNewPosPrev, _oldDelegateNewPosNext);\n\n uint256 oldDelUnbondingLockId = oldDel.nextUnbondingLockId.sub(1);\n uint256 withdrawRound = oldDel.unbondingLocks[oldDelUnbondingLockId].withdrawRound;\n\n // Burn lock for current owner\n delete oldDel.unbondingLocks[oldDelUnbondingLockId];\n\n // Create lock for new owner\n uint256 newDelUnbondingLockId = newDel.nextUnbondingLockId;\n\n newDel.unbondingLocks[newDelUnbondingLockId] = UnbondingLock({ amount: _amount, withdrawRound: withdrawRound });\n newDel.nextUnbondingLockId = newDel.nextUnbondingLockId.add(1);\n\n emit TransferBond(msg.sender, _delegator, oldDelUnbondingLockId, newDelUnbondingLockId, _amount);\n\n // Claim earnings for receiver before processing unbonding lock\n uint256 currentRound = roundsManager().currentRound();\n uint256 lastClaimRound = newDel.lastClaimRound;\n if (lastClaimRound < currentRound) {\n updateDelegatorWithEarnings(_delegator, currentRound, lastClaimRound);\n }\n\n // Rebond lock for new owner\n if (newDel.delegateAddress == address(0) && newDel.bondedAmount == 0) {\n // Requirements for caller\n // Does not trigger self-delegation\n require(oldDelDelegate != _delegator, \"INVALID_DELEGATOR\");\n // Does not transfer bond to the zero address\n require(address(0) != _delegator, \"INVALID_DELEGATOR\");\n\n // We do not need to call ensureInitializedCumulativeFactorsPool() here for oldDelDelegate because\n // the _autoClaimEarnings() call at the top of this function will already include a sub-call to\n // ensureInitializedCumulativeFactorsPool() for oldDelDelegate and the current round.\n\n newDel.delegateAddress = oldDelDelegate;\n }\n\n // Move to Pending state if receiver is currently in Unbonded state\n if (delegatorStatus(_delegator) == DelegatorStatus.Unbonded) {\n newDel.startRound = currentRound.add(1);\n }\n\n // Process rebond using unbonding lock\n processRebond(_delegator, newDelUnbondingLockId, _newDelegateNewPosPrev, _newDelegateNewPosNext);\n }\n\n /**\n * @notice Unbond an amount of the delegator's bonded stake and updates the transcoder pool using an optional list hint if needed\n * @dev If the caller remains in the transcoder pool, the caller can provide an optional hint for its insertion position in the\n * pool via the `_newPosPrev` and `_newPosNext` params. A linear search will be executed starting at the hint to find the correct position.\n * In the best case, the hint is the correct position so no search is executed. See SortedDoublyLL.sol details on list hints\n * @param _amount Amount of tokens to unbond\n * @param _newPosPrev Address of previous transcoder in pool if the caller remains in the pool\n * @param _newPosNext Address of next transcoder in pool if the caller remains in the pool\n */\n function unbondWithHint(\n uint256 _amount,\n address _newPosPrev,\n address _newPosNext\n ) public whenSystemNotPaused currentRoundInitialized autoClaimEarnings(msg.sender) autoCheckpoint(msg.sender) {\n require(delegatorStatus(msg.sender) == DelegatorStatus.Bonded, \"caller must be bonded\");\n\n Delegator storage del = delegators[msg.sender];\n\n require(_amount > 0, \"unbond amount must be greater than 0\");\n require(_amount <= del.bondedAmount, \"amount is greater than bonded amount\");\n\n address currentDelegate = del.delegateAddress;\n uint256 currentRound = roundsManager().currentRound();\n uint256 withdrawRound = currentRound.add(unbondingPeriod);\n uint256 unbondingLockId = del.nextUnbondingLockId;\n\n // Create new unbonding lock\n del.unbondingLocks[unbondingLockId] = UnbondingLock({ amount: _amount, withdrawRound: withdrawRound });\n // Increment ID for next unbonding lock\n del.nextUnbondingLockId = unbondingLockId.add(1);\n // Decrease delegator's bonded amount\n del.bondedAmount = del.bondedAmount.sub(_amount);\n\n if (del.bondedAmount == 0) {\n // Delegator no longer delegated to anyone if it does not have a bonded amount\n del.delegateAddress = address(0);\n // Delegator does not have a start round if it is no longer delegated to anyone\n del.startRound = 0;\n\n if (transcoderPool.contains(msg.sender)) {\n resignTranscoder(msg.sender);\n }\n }\n\n // If msg.sender was resigned this statement will only decrease delegators[currentDelegate].delegatedAmount\n decreaseTotalStake(currentDelegate, _amount, _newPosPrev, _newPosNext);\n if (currentDelegate != msg.sender) {\n // Avoid double checkpointing of the transcoder if it's a self-unbond\n _checkpointBondingState(currentDelegate, delegators[currentDelegate], transcoders[currentDelegate]);\n }\n\n emit Unbond(currentDelegate, msg.sender, unbondingLockId, _amount, withdrawRound);\n }\n\n /**\n * @notice Rebond tokens for an unbonding lock to a delegator's current delegate while a delegator is in the Bonded or Pending status and updates\n * the transcoder pool using an optional list hint if needed\n * @dev If the delegate is in the transcoder pool, the caller can provide an optional hint for the delegate's insertion position in the\n * pool via the `_newPosPrev` and `_newPosNext` params. A linear search will be executed starting at the hint to find the correct position.\n * In the best case, the hint is the correct position so no search is executed. See SortedDoublyLL.sol details on list hints\n * @param _unbondingLockId ID of unbonding lock to rebond with\n * @param _newPosPrev Address of previous transcoder in pool if the delegate is in the pool\n * @param _newPosNext Address of next transcoder in pool if the delegate is in the pool\n */\n function rebondWithHint(\n uint256 _unbondingLockId,\n address _newPosPrev,\n address _newPosNext\n ) public whenSystemNotPaused currentRoundInitialized autoClaimEarnings(msg.sender) {\n require(delegatorStatus(msg.sender) != DelegatorStatus.Unbonded, \"caller must be bonded\");\n\n // Process rebond using unbonding lock\n processRebond(msg.sender, _unbondingLockId, _newPosPrev, _newPosNext);\n }\n\n /**\n * @notice Rebond tokens for an unbonding lock to a delegate while a delegator is in the Unbonded status and updates the transcoder pool using\n * an optional list hint if needed\n * @dev If the delegate joins the transcoder pool, the caller can provide an optional hint for the delegate's insertion position in the\n * pool via the `_newPosPrev` and `_newPosNext` params. A linear search will be executed starting at the hint to find the correct position.\n * In the best case, the hint is the correct position so no search is executed. See SortedDoublyLL.sol for details on list hints\n * @param _to Address of delegate\n * @param _unbondingLockId ID of unbonding lock to rebond with\n * @param _newPosPrev Address of previous transcoder in pool if the delegate joins the pool\n * @param _newPosNext Address of next transcoder in pool if the delegate joins the pool\n */\n function rebondFromUnbondedWithHint(\n address _to,\n uint256 _unbondingLockId,\n address _newPosPrev,\n address _newPosNext\n ) public whenSystemNotPaused currentRoundInitialized autoClaimEarnings(msg.sender) {\n require(delegatorStatus(msg.sender) == DelegatorStatus.Unbonded, \"caller must be unbonded\");\n\n uint256 currentRound = roundsManager().currentRound();\n\n ensureInitializedCumulativeFactorsPool(_to, currentRound);\n\n // Set delegator's start round and transition into Pending state\n delegators[msg.sender].startRound = currentRound.add(1);\n // Set delegator's delegate\n delegators[msg.sender].delegateAddress = _to;\n // Process rebond using unbonding lock\n processRebond(msg.sender, _unbondingLockId, _newPosPrev, _newPosNext);\n }\n\n /**\n * @notice Mint token rewards for an active transcoder and its delegators and update the transcoder pool using an optional list hint if needed\n * @dev If the caller is in the transcoder pool, the caller can provide an optional hint for its insertion position in the\n * pool via the `_newPosPrev` and `_newPosNext` params. A linear search will be executed starting at the hint to find the correct position.\n * In the best case, the hint is the correct position so no search is executed. See SortedDoublyLL.sol for details on list hints\n * @param _newPosPrev Address of previous transcoder in pool if the caller is in the pool\n * @param _newPosNext Address of next transcoder in pool if the caller is in the pool\n */\n function rewardWithHint(address _newPosPrev, address _newPosNext)\n public\n whenSystemNotPaused\n currentRoundInitialized\n autoCheckpoint(msg.sender)\n {\n uint256 currentRound = roundsManager().currentRound();\n\n require(isActiveTranscoder(msg.sender), \"caller must be an active transcoder\");\n require(\n transcoders[msg.sender].lastRewardRound != currentRound,\n \"caller has already called reward for the current round\"\n );\n\n Transcoder storage t = transcoders[msg.sender];\n EarningsPool.Data storage earningsPool = t.earningsPoolPerRound[currentRound];\n\n // Set last round that transcoder called reward\n earningsPool.setCommission(t.rewardCut, t.feeShare);\n\n // If transcoder didn't receive stake updates during the previous round and hasn't called reward for > 1 round\n // the 'totalStake' on its 'EarningsPool' for the current round wouldn't be initialized\n // Thus we sync the the transcoder's stake to when it was last updated\n // 'updateTrancoderWithRewards()' will set the update round to 'currentRound +1' so this synchronization shouldn't occur frequently\n uint256 lastUpdateRound = t.lastActiveStakeUpdateRound;\n if (lastUpdateRound < currentRound) {\n earningsPool.setStake(t.earningsPoolPerRound[lastUpdateRound].totalStake);\n }\n\n if (treasuryBalanceCeiling > 0) {\n uint256 treasuryBalance = livepeerToken().balanceOf(treasury());\n if (treasuryBalance >= treasuryBalanceCeiling && nextRoundTreasuryRewardCutRate > 0) {\n // halt treasury contributions until the cut rate param is updated again\n _setTreasuryRewardCutRate(0);\n }\n }\n\n // Create reward based on active transcoder's stake relative to the total active stake\n // rewardTokens = (current mintable tokens for the round * active transcoder stake) / total active stake\n IMinter mtr = minter();\n uint256 totalRewardTokens = mtr.createReward(earningsPool.totalStake, currentRoundTotalActiveStake);\n uint256 treasuryRewards = PreciseMathUtils.percOf(totalRewardTokens, treasuryRewardCutRate);\n if (treasuryRewards > 0) {\n address trsry = treasury();\n\n mtr.trustedTransferTokens(trsry, treasuryRewards);\n\n emit TreasuryReward(msg.sender, trsry, treasuryRewards);\n }\n\n uint256 transcoderRewards = totalRewardTokens.sub(treasuryRewards);\n\n updateTranscoderWithRewards(msg.sender, transcoderRewards, currentRound, _newPosPrev, _newPosNext);\n\n // Set last round that transcoder called reward\n t.lastRewardRound = currentRound;\n\n emit Reward(msg.sender, transcoderRewards);\n }\n\n /**\n * @notice Returns pending bonded stake for a delegator from its lastClaimRound through an end round\n * @param _delegator Address of delegator\n * @param _endRound Unused, but used to represent the last round to compute pending stake from. Currently, the\n * pending stake is always calculated for the current round instead.\n * @return Pending bonded stake for '_delegator' since last claiming rewards\n */\n function pendingStake(address _delegator, uint256 _endRound) public view returns (uint256) {\n // Silence unused param compiler warning\n _endRound;\n\n uint256 endRound = roundsManager().currentRound();\n (uint256 stake, ) = pendingStakeAndFees(_delegator, endRound);\n return stake;\n }\n\n /**\n * @notice Returns pending fees for a delegator from its lastClaimRound through an end round\n * @param _delegator Address of delegator\n * @param _endRound Unused, but used to represent the last round to compute pending fees from. Currently, the\n * pending fees are always calculated for the current round instead.\n * @return Pending fees for '_delegator' since last claiming fees\n */\n function pendingFees(address _delegator, uint256 _endRound) public view returns (uint256) {\n // Silence unused param compiler warning\n _endRound;\n\n uint256 endRound = roundsManager().currentRound();\n (, uint256 fees) = pendingStakeAndFees(_delegator, endRound);\n return fees;\n }\n\n /**\n * @notice Returns total bonded stake for a transcoder\n * @param _transcoder Address of transcoder\n * @return total bonded stake for a delegator\n */\n function transcoderTotalStake(address _transcoder) public view returns (uint256) {\n return delegators[_transcoder].delegatedAmount;\n }\n\n /**\n * @notice Computes transcoder status\n * @param _transcoder Address of transcoder\n * @return registered or not registered transcoder status\n */\n function transcoderStatus(address _transcoder) public view returns (TranscoderStatus) {\n if (isRegisteredTranscoder(_transcoder)) return TranscoderStatus.Registered;\n return TranscoderStatus.NotRegistered;\n }\n\n /**\n * @notice Computes delegator status\n * @param _delegator Address of delegator\n * @return bonded, unbonded or pending delegator status\n */\n function delegatorStatus(address _delegator) public view returns (DelegatorStatus) {\n Delegator storage del = delegators[_delegator];\n\n if (del.bondedAmount == 0) {\n // Delegator unbonded all its tokens\n return DelegatorStatus.Unbonded;\n } else if (del.startRound > roundsManager().currentRound()) {\n // Delegator round start is in the future\n return DelegatorStatus.Pending;\n } else {\n // Delegator round start is now or in the past\n // del.startRound != 0 here because if del.startRound = 0 then del.bondedAmount = 0 which\n // would trigger the first if clause\n return DelegatorStatus.Bonded;\n }\n }\n\n /**\n * @notice Return transcoder information\n * @param _transcoder Address of transcoder\n * @return lastRewardRound Trancoder's last reward round\n * @return rewardCut Transcoder's reward cut\n * @return feeShare Transcoder's fee share\n * @return lastActiveStakeUpdateRound Round in which transcoder's stake was last updated while active\n * @return activationRound Round in which transcoder became active\n * @return deactivationRound Round in which transcoder will no longer be active\n * @return activeCumulativeRewards Transcoder's cumulative rewards that are currently active\n * @return cumulativeRewards Transcoder's cumulative rewards (earned via its active staked rewards and its reward cut)\n * @return cumulativeFees Transcoder's cumulative fees (earned via its active staked rewards and its fee share)\n * @return lastFeeRound Latest round that the transcoder received fees\n */\n function getTranscoder(address _transcoder)\n public\n view\n returns (\n uint256 lastRewardRound,\n uint256 rewardCut,\n uint256 feeShare,\n uint256 lastActiveStakeUpdateRound,\n uint256 activationRound,\n uint256 deactivationRound,\n uint256 activeCumulativeRewards,\n uint256 cumulativeRewards,\n uint256 cumulativeFees,\n uint256 lastFeeRound\n )\n {\n Transcoder storage t = transcoders[_transcoder];\n\n lastRewardRound = t.lastRewardRound;\n rewardCut = t.rewardCut;\n feeShare = t.feeShare;\n lastActiveStakeUpdateRound = t.lastActiveStakeUpdateRound;\n activationRound = t.activationRound;\n deactivationRound = t.deactivationRound;\n activeCumulativeRewards = t.activeCumulativeRewards;\n cumulativeRewards = t.cumulativeRewards;\n cumulativeFees = t.cumulativeFees;\n lastFeeRound = t.lastFeeRound;\n }\n\n /**\n * @notice Return transcoder's earnings pool for a given round\n * @param _transcoder Address of transcoder\n * @param _round Round number\n * @return totalStake Transcoder's total stake in '_round'\n * @return transcoderRewardCut Transcoder's reward cut for '_round'\n * @return transcoderFeeShare Transcoder's fee share for '_round'\n * @return cumulativeRewardFactor The cumulative reward factor for delegator rewards calculation (only used after LIP-36)\n * @return cumulativeFeeFactor The cumulative fee factor for delegator fees calculation (only used after LIP-36)\n */\n function getTranscoderEarningsPoolForRound(address _transcoder, uint256 _round)\n public\n view\n returns (\n uint256 totalStake,\n uint256 transcoderRewardCut,\n uint256 transcoderFeeShare,\n uint256 cumulativeRewardFactor,\n uint256 cumulativeFeeFactor\n )\n {\n EarningsPool.Data storage earningsPool = transcoders[_transcoder].earningsPoolPerRound[_round];\n\n totalStake = earningsPool.totalStake;\n transcoderRewardCut = earningsPool.transcoderRewardCut;\n transcoderFeeShare = earningsPool.transcoderFeeShare;\n cumulativeRewardFactor = earningsPool.cumulativeRewardFactor;\n cumulativeFeeFactor = earningsPool.cumulativeFeeFactor;\n }\n\n /**\n * @notice Return delegator info\n * @param _delegator Address of delegator\n * @return bondedAmount total amount bonded by '_delegator'\n * @return fees amount of fees collected by '_delegator'\n * @return delegateAddress address '_delegator' has bonded to\n * @return delegatedAmount total amount delegated to '_delegator'\n * @return startRound round in which bond for '_delegator' became effective\n * @return lastClaimRound round for which '_delegator' has last claimed earnings\n * @return nextUnbondingLockId ID for the next unbonding lock created for '_delegator'\n */\n function getDelegator(address _delegator)\n public\n view\n returns (\n uint256 bondedAmount,\n uint256 fees,\n address delegateAddress,\n uint256 delegatedAmount,\n uint256 startRound,\n uint256 lastClaimRound,\n uint256 nextUnbondingLockId\n )\n {\n Delegator storage del = delegators[_delegator];\n\n bondedAmount = del.bondedAmount;\n fees = del.fees;\n delegateAddress = del.delegateAddress;\n delegatedAmount = del.delegatedAmount;\n startRound = del.startRound;\n lastClaimRound = del.lastClaimRound;\n nextUnbondingLockId = del.nextUnbondingLockId;\n }\n\n /**\n * @notice Return delegator's unbonding lock info\n * @param _delegator Address of delegator\n * @param _unbondingLockId ID of unbonding lock\n * @return amount of stake locked up by unbonding lock\n * @return withdrawRound round in which 'amount' becomes available for withdrawal\n */\n function getDelegatorUnbondingLock(address _delegator, uint256 _unbondingLockId)\n public\n view\n returns (uint256 amount, uint256 withdrawRound)\n {\n UnbondingLock storage lock = delegators[_delegator].unbondingLocks[_unbondingLockId];\n\n return (lock.amount, lock.withdrawRound);\n }\n\n /**\n * @notice Returns max size of transcoder pool\n * @return transcoder pool max size\n */\n function getTranscoderPoolMaxSize() public view returns (uint256) {\n return transcoderPool.getMaxSize();\n }\n\n /**\n * @notice Returns size of transcoder pool\n * @return transcoder pool current size\n */\n function getTranscoderPoolSize() public view returns (uint256) {\n return transcoderPool.getSize();\n }\n\n /**\n * @notice Returns transcoder with most stake in pool\n * @return address for transcoder with highest stake in transcoder pool\n */\n function getFirstTranscoderInPool() public view returns (address) {\n return transcoderPool.getFirst();\n }\n\n /**\n * @notice Returns next transcoder in pool for a given transcoder\n * @param _transcoder Address of a transcoder in the pool\n * @return address for the transcoder after '_transcoder' in transcoder pool\n */\n function getNextTranscoderInPool(address _transcoder) public view returns (address) {\n return transcoderPool.getNext(_transcoder);\n }\n\n /**\n * @notice Return total bonded tokens\n * @return total active stake for the current round\n */\n function getTotalBonded() public view returns (uint256) {\n return currentRoundTotalActiveStake;\n }\n\n /**\n * @notice Return whether a transcoder is active for the current round\n * @param _transcoder Transcoder address\n * @return true if transcoder is active\n */\n function isActiveTranscoder(address _transcoder) public view returns (bool) {\n Transcoder storage t = transcoders[_transcoder];\n uint256 currentRound = roundsManager().currentRound();\n return t.activationRound <= currentRound && currentRound < t.deactivationRound;\n }\n\n /**\n * @notice Return whether a transcoder is registered\n * @param _transcoder Transcoder address\n * @return true if transcoder is self-bonded\n */\n function isRegisteredTranscoder(address _transcoder) public view returns (bool) {\n Delegator storage d = delegators[_transcoder];\n return d.delegateAddress == _transcoder && d.bondedAmount > 0;\n }\n\n /**\n * @notice Return whether an unbonding lock for a delegator is valid\n * @param _delegator Address of delegator\n * @param _unbondingLockId ID of unbonding lock\n * @return true if unbondingLock for ID has a non-zero withdraw round\n */\n function isValidUnbondingLock(address _delegator, uint256 _unbondingLockId) public view returns (bool) {\n // A unbonding lock is only valid if it has a non-zero withdraw round (the default value is zero)\n return delegators[_delegator].unbondingLocks[_unbondingLockId].withdrawRound > 0;\n }\n\n /**\n * @dev Internal version of setTreasuryRewardCutRate. Sets the treasury reward cut rate for the next round and emits\n * corresponding event.\n */\n function _setTreasuryRewardCutRate(uint256 _cutRate) internal {\n require(PreciseMathUtils.validPerc(_cutRate), \"_cutRate is invalid precise percentage\");\n\n nextRoundTreasuryRewardCutRate = _cutRate;\n\n emit ParameterUpdate(\"nextRoundTreasuryRewardCutRate\");\n }\n\n /**\n * @notice Return an EarningsPool.Data struct with cumulative factors for a given round that are rescaled if needed\n * @param _transcoder Storage pointer to a transcoder struct\n * @param _round The round to fetch the cumulative factors for\n */\n function cumulativeFactorsPool(Transcoder storage _transcoder, uint256 _round)\n internal\n view\n returns (EarningsPool.Data memory pool)\n {\n pool.cumulativeRewardFactor = _transcoder.earningsPoolPerRound[_round].cumulativeRewardFactor;\n pool.cumulativeFeeFactor = _transcoder.earningsPoolPerRound[_round].cumulativeFeeFactor;\n\n return pool;\n }\n\n /**\n * @notice Return an EarningsPool.Data struct with the latest cumulative factors for a given round\n * @param _transcoder Storage pointer to a transcoder struct\n * @param _round The round to fetch the latest cumulative factors for\n * @return pool An EarningsPool.Data populated with the latest cumulative factors for _round\n */\n function latestCumulativeFactorsPool(Transcoder storage _transcoder, uint256 _round)\n internal\n view\n returns (EarningsPool.Data memory pool)\n {\n pool = cumulativeFactorsPool(_transcoder, _round);\n\n uint256 lastRewardRound = _transcoder.lastRewardRound;\n // Only use the cumulativeRewardFactor for lastRewardRound if lastRewardRound is before _round\n if (pool.cumulativeRewardFactor == 0 && lastRewardRound < _round) {\n pool.cumulativeRewardFactor = cumulativeFactorsPool(_transcoder, lastRewardRound).cumulativeRewardFactor;\n }\n\n uint256 lastFeeRound = _transcoder.lastFeeRound;\n // Only use the cumulativeFeeFactor for lastFeeRound if lastFeeRound is before _round\n if (pool.cumulativeFeeFactor == 0 && lastFeeRound < _round) {\n pool.cumulativeFeeFactor = cumulativeFactorsPool(_transcoder, lastFeeRound).cumulativeFeeFactor;\n }\n\n return pool;\n }\n\n /**\n * @notice Return a delegator's cumulative stake and fees using the LIP-36 earnings claiming algorithm\n * @param _transcoder Storage pointer to a transcoder struct for a delegator's delegate\n * @param _startRound The round for the start cumulative factors\n * @param _endRound The round for the end cumulative factors. Normally this is the current round as historical\n * lookup is only supported through BondingVotes\n * @param _stake The delegator's initial stake before including earned rewards\n * @param _fees The delegator's initial fees before including earned fees\n * @return cStake , cFees where cStake is the delegator's cumulative stake including earned rewards and cFees is the delegator's cumulative fees including earned fees\n */\n function delegatorCumulativeStakeAndFees(\n Transcoder storage _transcoder,\n uint256 _startRound,\n uint256 _endRound,\n uint256 _stake,\n uint256 _fees\n ) internal view returns (uint256 cStake, uint256 cFees) {\n // Fetch start cumulative factors\n EarningsPool.Data memory startPool = cumulativeFactorsPool(_transcoder, _startRound);\n // Fetch end cumulative factors\n EarningsPool.Data memory endPool = latestCumulativeFactorsPool(_transcoder, _endRound);\n\n return EarningsPoolLIP36.delegatorCumulativeStakeAndFees(startPool, endPool, _stake, _fees);\n }\n\n /**\n * @notice Return the pending stake and fees for a delegator\n * @param _delegator Address of a delegator\n * @param _endRound The last round to claim earnings for when calculating the pending stake and fees\n * @return stake , fees where stake is the delegator's pending stake and fees is the delegator's pending fees\n */\n function pendingStakeAndFees(address _delegator, uint256 _endRound)\n internal\n view\n returns (uint256 stake, uint256 fees)\n {\n Delegator storage del = delegators[_delegator];\n Transcoder storage t = transcoders[del.delegateAddress];\n\n fees = del.fees;\n stake = del.bondedAmount;\n\n uint256 startRound = del.lastClaimRound.add(1);\n address delegateAddr = del.delegateAddress;\n bool isTranscoder = _delegator == delegateAddr;\n\n // Make sure there is a round to claim i.e. end round - (start round - 1) > 0\n if (startRound <= _endRound) {\n (stake, fees) = delegatorCumulativeStakeAndFees(t, startRound.sub(1), _endRound, stake, fees);\n }\n // cumulativeRewards and cumulativeFees will track *all* rewards/fees earned by the transcoder\n // so it is important that this is only executed with the end round as the current round or else\n // the returned stake and fees will reflect rewards/fees earned in the future relative to the end round\n if (isTranscoder) {\n stake = stake.add(t.cumulativeRewards);\n fees = fees.add(t.cumulativeFees);\n }\n\n return (stake, fees);\n }\n\n /**\n * @dev Increase the total stake for a delegate and updates its 'lastActiveStakeUpdateRound'. Notice that this\n * function does not checkpoint the delegate and callers should take care of it themselves.\n * @param _delegate The delegate to increase the stake for\n * @param _amount The amount to increase the stake for '_delegate' by\n */\n function increaseTotalStake(\n address _delegate,\n uint256 _amount,\n address _newPosPrev,\n address _newPosNext\n ) internal {\n Transcoder storage t = transcoders[_delegate];\n\n uint256 currStake = transcoderTotalStake(_delegate);\n uint256 newStake = currStake.add(_amount);\n\n if (isRegisteredTranscoder(_delegate)) {\n uint256 currRound = roundsManager().currentRound();\n uint256 nextRound = currRound.add(1);\n\n // If the transcoder is already in the active set update its stake and return\n if (transcoderPool.contains(_delegate)) {\n transcoderPool.updateKey(_delegate, newStake, _newPosPrev, _newPosNext);\n nextRoundTotalActiveStake = nextRoundTotalActiveStake.add(_amount);\n\n // currStake (the transcoder's delegatedAmount field) will reflect the transcoder's stake from lastActiveStakeUpdateRound\n // because it is updated every time lastActiveStakeUpdateRound is updated\n // The current active total stake is set to currStake to ensure that the value can be used in updateTranscoderWithRewards()\n // and updateTranscoderWithFees() when lastActiveStakeUpdateRound > currentRound\n if (t.lastActiveStakeUpdateRound < currRound) {\n t.earningsPoolPerRound[currRound].setStake(currStake);\n }\n\n t.earningsPoolPerRound[nextRound].setStake(newStake);\n t.lastActiveStakeUpdateRound = nextRound;\n } else {\n // Check if the transcoder is eligible to join the active set in the update round\n tryToJoinActiveSet(_delegate, newStake, nextRound, _newPosPrev, _newPosNext);\n }\n }\n\n // Increase delegate's delegated amount\n delegators[_delegate].delegatedAmount = newStake;\n }\n\n /**\n * @dev Decrease the total stake for a delegate and updates its 'lastActiveStakeUpdateRound'\n * @param _delegate The transcoder to decrease the stake for\n * @param _amount The amount to decrease the stake for '_delegate' by\n */\n function decreaseTotalStake(\n address _delegate,\n uint256 _amount,\n address _newPosPrev,\n address _newPosNext\n ) internal {\n Transcoder storage t = transcoders[_delegate];\n\n uint256 currStake = transcoderTotalStake(_delegate);\n uint256 newStake = currStake.sub(_amount);\n\n if (transcoderPool.contains(_delegate)) {\n uint256 currRound = roundsManager().currentRound();\n uint256 nextRound = currRound.add(1);\n\n transcoderPool.updateKey(_delegate, newStake, _newPosPrev, _newPosNext);\n nextRoundTotalActiveStake = nextRoundTotalActiveStake.sub(_amount);\n\n // currStake (the transcoder's delegatedAmount field) will reflect the transcoder's stake from lastActiveStakeUpdateRound\n // because it is updated every time lastActiveStakeUpdateRound is updated\n // The current active total stake is set to currStake to ensure that the value can be used in updateTranscoderWithRewards()\n // and updateTranscoderWithFees() when lastActiveStakeUpdateRound > currentRound\n if (t.lastActiveStakeUpdateRound < currRound) {\n t.earningsPoolPerRound[currRound].setStake(currStake);\n }\n\n t.lastActiveStakeUpdateRound = nextRound;\n t.earningsPoolPerRound[nextRound].setStake(newStake);\n }\n\n // Decrease old delegate's delegated amount\n delegators[_delegate].delegatedAmount = newStake;\n }\n\n /**\n * @dev Tries to add a transcoder to active transcoder pool, evicts the active transcoder with the lowest stake if the pool is full\n * @param _transcoder The transcoder to insert into the transcoder pool\n * @param _totalStake The total stake for '_transcoder'\n * @param _activationRound The round in which the transcoder should become active\n */\n function tryToJoinActiveSet(\n address _transcoder,\n uint256 _totalStake,\n uint256 _activationRound,\n address _newPosPrev,\n address _newPosNext\n ) internal {\n uint256 pendingNextRoundTotalActiveStake = nextRoundTotalActiveStake;\n\n if (transcoderPool.isFull()) {\n address lastTranscoder = transcoderPool.getLast();\n uint256 lastStake = transcoderTotalStake(lastTranscoder);\n\n // If the pool is full and the transcoder has less stake than the least stake transcoder in the pool\n // then the transcoder is unable to join the active set for the next round\n if (_totalStake <= lastStake) {\n return;\n }\n\n // Evict the least stake transcoder from the active set for the next round\n // Not zeroing 'Transcoder.lastActiveStakeUpdateRound' saves gas (5k when transcoder is evicted and 20k when transcoder is reinserted)\n // There should be no side-effects as long as the value is properly updated on stake updates\n // Not zeroing the stake on the current round's 'EarningsPool' saves gas and should have no side effects as long as\n // 'EarningsPool.setStake()' is called whenever a transcoder becomes active again.\n transcoderPool.remove(lastTranscoder);\n transcoders[lastTranscoder].deactivationRound = _activationRound;\n pendingNextRoundTotalActiveStake = pendingNextRoundTotalActiveStake.sub(lastStake);\n\n emit TranscoderDeactivated(lastTranscoder, _activationRound);\n }\n\n transcoderPool.insert(_transcoder, _totalStake, _newPosPrev, _newPosNext);\n pendingNextRoundTotalActiveStake = pendingNextRoundTotalActiveStake.add(_totalStake);\n Transcoder storage t = transcoders[_transcoder];\n t.lastActiveStakeUpdateRound = _activationRound;\n t.activationRound = _activationRound;\n t.deactivationRound = MAX_FUTURE_ROUND;\n t.earningsPoolPerRound[_activationRound].setStake(_totalStake);\n nextRoundTotalActiveStake = pendingNextRoundTotalActiveStake;\n emit TranscoderActivated(_transcoder, _activationRound);\n }\n\n /**\n * @dev Remove a transcoder from the pool and deactivate it\n */\n function resignTranscoder(address _transcoder) internal {\n // Not zeroing 'Transcoder.lastActiveStakeUpdateRound' saves gas (5k when transcoder is evicted and 20k when transcoder is reinserted)\n // There should be no side-effects as long as the value is properly updated on stake updates\n // Not zeroing the stake on the current round's 'EarningsPool' saves gas and should have no side effects as long as\n // 'EarningsPool.setStake()' is called whenever a transcoder becomes active again.\n transcoderPool.remove(_transcoder);\n nextRoundTotalActiveStake = nextRoundTotalActiveStake.sub(transcoderTotalStake(_transcoder));\n uint256 deactivationRound = roundsManager().currentRound().add(1);\n transcoders[_transcoder].deactivationRound = deactivationRound;\n emit TranscoderDeactivated(_transcoder, deactivationRound);\n }\n\n /**\n * @dev Update a transcoder with rewards and update the transcoder pool with an optional list hint if needed.\n * See SortedDoublyLL.sol for details on list hints. This function updates the transcoder state but does not\n * checkpoint it as it assumes the caller will ensure that.\n * @param _transcoder Address of transcoder\n * @param _rewards Amount of rewards\n * @param _round Round that transcoder is updated\n * @param _newPosPrev Address of previous transcoder in pool if the transcoder is in the pool\n * @param _newPosNext Address of next transcoder in pool if the transcoder is in the pool\n */\n function updateTranscoderWithRewards(\n address _transcoder,\n uint256 _rewards,\n uint256 _round,\n address _newPosPrev,\n address _newPosNext\n ) internal {\n Transcoder storage t = transcoders[_transcoder];\n EarningsPool.Data storage earningsPool = t.earningsPoolPerRound[_round];\n EarningsPool.Data memory prevEarningsPool = cumulativeFactorsPool(t, t.lastRewardRound);\n\n t.activeCumulativeRewards = t.cumulativeRewards;\n\n uint256 transcoderCommissionRewards = MathUtils.percOf(_rewards, earningsPool.transcoderRewardCut);\n uint256 delegatorsRewards = _rewards.sub(transcoderCommissionRewards);\n // Calculate the rewards earned by the transcoder's earned rewards\n uint256 transcoderRewardStakeRewards = PreciseMathUtils.percOf(\n delegatorsRewards,\n t.activeCumulativeRewards,\n earningsPool.totalStake\n );\n // Track rewards earned by the transcoder based on its earned rewards and rewardCut\n t.cumulativeRewards = t.cumulativeRewards.add(transcoderRewardStakeRewards).add(transcoderCommissionRewards);\n // Update cumulative reward factor with new rewards\n // The cumulativeRewardFactor is used to calculate rewards for all delegators including the transcoder (self-delegated)\n // Note that delegatorsRewards includes transcoderRewardStakeRewards, but no delegator will claim that amount using\n // the earnings claiming algorithm and instead that amount is accounted for in the transcoder's cumulativeRewards field\n earningsPool.updateCumulativeRewardFactor(prevEarningsPool, delegatorsRewards);\n // Update transcoder's total stake with rewards\n increaseTotalStake(_transcoder, _rewards, _newPosPrev, _newPosNext);\n }\n\n /**\n * @dev Update a delegator with token pools shares from its lastClaimRound through a given round\n *\n * Notice that this function updates the delegator storage but does not checkpoint its state. Since it is internal\n * it assumes the top-level caller will checkpoint it instead.\n * @param _delegator Delegator address\n * @param _endRound The last round for which to update a delegator's stake with earnings pool shares\n * @param _lastClaimRound The round for which a delegator has last claimed earnings\n */\n function updateDelegatorWithEarnings(\n address _delegator,\n uint256 _endRound,\n uint256 _lastClaimRound\n ) internal {\n Delegator storage del = delegators[_delegator];\n uint256 startRound = _lastClaimRound.add(1);\n uint256 currentBondedAmount = del.bondedAmount;\n uint256 currentFees = del.fees;\n\n // Only will have earnings to claim if you have a delegate\n // If not delegated, skip the earnings claim process\n if (del.delegateAddress != address(0)) {\n (currentBondedAmount, currentFees) = pendingStakeAndFees(_delegator, _endRound);\n\n // Check whether the endEarningsPool is initialised\n // If it is not initialised set it's cumulative factors so that they can be used when a delegator\n // next claims earnings as the start cumulative factors (see delegatorCumulativeStakeAndFees())\n address delegate = del.delegateAddress;\n ensureInitializedCumulativeFactorsPool(delegate, _endRound);\n\n if (del.delegateAddress == _delegator) {\n Transcoder storage t = transcoders[delegate];\n t.cumulativeFees = 0;\n t.cumulativeRewards = 0;\n // activeCumulativeRewards is not cleared here because the next reward() call will set it to cumulativeRewards\n }\n }\n\n emit EarningsClaimed(\n del.delegateAddress,\n _delegator,\n currentBondedAmount.sub(del.bondedAmount),\n currentFees.sub(del.fees),\n startRound,\n _endRound\n );\n\n del.lastClaimRound = _endRound;\n // Rewards are bonded by default\n del.bondedAmount = currentBondedAmount;\n del.fees = currentFees;\n }\n\n /**\n * @dev Update the state of a delegator and its delegate by processing a rebond using an unbonding lock and update the transcoder pool with an optional\n * list hint if needed. See SortedDoublyLL.sol for details on list hints\n * @param _delegator Address of delegator\n * @param _unbondingLockId ID of unbonding lock to rebond with\n * @param _newPosPrev Address of previous transcoder in pool if the delegate is already in or joins the pool\n * @param _newPosNext Address of next transcoder in pool if the delegate is already in or joins the pool\n */\n function processRebond(\n address _delegator,\n uint256 _unbondingLockId,\n address _newPosPrev,\n address _newPosNext\n ) internal autoCheckpoint(_delegator) {\n Delegator storage del = delegators[_delegator];\n UnbondingLock storage lock = del.unbondingLocks[_unbondingLockId];\n\n require(isValidUnbondingLock(_delegator, _unbondingLockId), \"invalid unbonding lock ID\");\n\n uint256 amount = lock.amount;\n // Increase delegator's bonded amount\n del.bondedAmount = del.bondedAmount.add(amount);\n\n // Delete lock\n delete del.unbondingLocks[_unbondingLockId];\n\n address delegate = del.delegateAddress;\n\n increaseTotalStake(delegate, amount, _newPosPrev, _newPosNext);\n if (delegate != _delegator) {\n // Avoid double checkpointing of the transcoder if it's a self-rebond\n _checkpointBondingState(delegate, delegators[delegate], transcoders[delegate]);\n }\n\n emit Rebond(delegate, _delegator, _unbondingLockId, amount);\n }\n\n function ensureInitializedCumulativeFactorsPool(address _transcoder, uint256 _round) internal {\n Transcoder storage t = transcoders[_transcoder];\n EarningsPool.Data storage pool = t.earningsPoolPerRound[_round];\n if (pool.cumulativeRewardFactor == 0) {\n uint256 lastRewardRound = t.lastRewardRound;\n if (lastRewardRound < _round) {\n pool.cumulativeRewardFactor = cumulativeFactorsPool(t, lastRewardRound).cumulativeRewardFactor;\n }\n }\n if (pool.cumulativeFeeFactor == 0) {\n uint256 lastFeeRound = t.lastFeeRound;\n if (lastFeeRound < _round) {\n pool.cumulativeFeeFactor = cumulativeFactorsPool(t, lastFeeRound).cumulativeFeeFactor;\n }\n }\n }\n\n /**\n * @notice Checkpoints a delegator state after changes, to be used for historical voting power calculations in\n * on-chain governor logic.\n */\n function _checkpointBondingState(\n address _owner,\n Delegator storage _delegator,\n Transcoder storage _transcoder\n ) internal {\n // start round refers to the round where the checkpointed stake will be active. The actual `startRound` value\n // in the delegators doesn't get updated on bond or claim earnings though, so we use currentRound() + 1\n // which is the only guaranteed round where the currently stored stake will be active.\n uint256 startRound = roundsManager().currentRound() + 1;\n bondingVotes().checkpointBondingState(\n _owner,\n startRound,\n _delegator.bondedAmount,\n _delegator.delegateAddress,\n _delegator.delegatedAmount,\n _delegator.lastClaimRound,\n _transcoder.lastRewardRound\n );\n }\n\n /**\n * @dev Return LivepeerToken interface\n * @return Livepeer token contract registered with Controller\n */\n function livepeerToken() internal view returns (ILivepeerToken) {\n return ILivepeerToken(controller.getContract(keccak256(\"LivepeerToken\")));\n }\n\n /**\n * @dev Return Minter interface\n * @return Minter contract registered with Controller\n */\n function minter() internal view returns (IMinter) {\n return IMinter(controller.getContract(keccak256(\"Minter\")));\n }\n\n /**\n * @dev Return Address of L2Migrator\n * @return l2Migrator contract address registered with Controller\n */\n function l2Migrator() internal view returns (address) {\n return controller.getContract(keccak256(\"L2Migrator\"));\n }\n\n /**\n * @dev Return RoundsManager interface\n * @return RoundsManager contract registered with Controller\n */\n function roundsManager() internal view returns (IRoundsManager) {\n return IRoundsManager(controller.getContract(keccak256(\"RoundsManager\")));\n }\n\n function treasury() internal view returns (address) {\n return controller.getContract(keccak256(\"Treasury\"));\n }\n\n function bondingVotes() internal view returns (IBondingVotes) {\n return IBondingVotes(controller.getContract(keccak256(\"BondingVotes\")));\n }\n\n function _onlyTicketBroker() internal view {\n require(msg.sender == controller.getContract(keccak256(\"TicketBroker\")), \"caller must be TicketBroker\");\n }\n\n function _onlyRoundsManager() internal view {\n require(msg.sender == controller.getContract(keccak256(\"RoundsManager\")), \"caller must be RoundsManager\");\n }\n\n function _onlyVerifier() internal view {\n require(msg.sender == controller.getContract(keccak256(\"Verifier\")), \"caller must be Verifier\");\n }\n\n function _currentRoundInitialized() internal view {\n require(roundsManager().currentRoundInitialized(), \"current round is not initialized\");\n }\n\n function _autoClaimEarnings(address _delegator) internal {\n uint256 currentRound = roundsManager().currentRound();\n uint256 lastClaimRound = delegators[_delegator].lastClaimRound;\n if (lastClaimRound < currentRound) {\n updateDelegatorWithEarnings(_delegator, currentRound, lastClaimRound);\n }\n }\n\n /**\n * @notice Check whether the msg.sender should be able to trigger earnings claiming for an address.\n * @dev This function currently restricts a third party from being able to trigger earnings claiming before a\n * delegator's active transcoder calls reward in a round. This is to ensure the delegator controls the timing of\n * reward claiming so they don't miss on round rewards. This function could be updated in a future LIP to support\n * more flexible authorization logic.\n */\n function _authorizeClaimEarnings(address _owner) internal view {\n if (msg.sender == _owner || msg.sender == l2Migrator() || delegatorStatus(_owner) == DelegatorStatus.Unbonded) {\n return;\n }\n\n Delegator storage del = delegators[_owner];\n address delegate = del.delegateAddress;\n if (!isActiveTranscoder(delegate)) {\n // Only delegators to active transcoders are subject to this accounting issue.\n return;\n }\n\n uint256 currentRound = roundsManager().currentRound();\n Transcoder storage t = transcoders[delegate];\n require(t.lastRewardRound == currentRound || del.lastClaimRound == currentRound, \"ILLEGAL_CLAIM_EARNINGS\");\n }\n}\n" + }, + "contracts/ManagerProxyTarget.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./Manager.sol\";\n\n/**\n * @title ManagerProxyTarget\n * @notice The base contract that target contracts used by a proxy contract should inherit from\n * @dev Both the target contract and the proxy contract (implemented as ManagerProxy) MUST inherit from ManagerProxyTarget in order to guarantee\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\n potentially break the delegate proxy upgradeability mechanism\n */\nabstract contract ManagerProxyTarget is Manager {\n // Used to look up target contract address in controller's registry\n bytes32 public targetContractId;\n}\n" + }, + "contracts/bonding/IBondingManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\n/**\n * @title Interface for BondingManager\n * TODO: switch to interface type\n */\ninterface IBondingManager {\n event TranscoderUpdate(address indexed transcoder, uint256 rewardCut, uint256 feeShare);\n event TranscoderActivated(address indexed transcoder, uint256 activationRound);\n event TranscoderDeactivated(address indexed transcoder, uint256 deactivationRound);\n event TranscoderSlashed(address indexed transcoder, address finder, uint256 penalty, uint256 finderReward);\n event Reward(address indexed transcoder, uint256 amount);\n event TreasuryReward(address indexed transcoder, address treasury, uint256 amount);\n event Bond(\n address indexed newDelegate,\n address indexed oldDelegate,\n address indexed delegator,\n uint256 additionalAmount,\n uint256 bondedAmount\n );\n event Unbond(\n address indexed delegate,\n address indexed delegator,\n uint256 unbondingLockId,\n uint256 amount,\n uint256 withdrawRound\n );\n event Rebond(address indexed delegate, address indexed delegator, uint256 unbondingLockId, uint256 amount);\n event TransferBond(\n address indexed oldDelegator,\n address indexed newDelegator,\n uint256 oldUnbondingLockId,\n uint256 newUnbondingLockId,\n uint256 amount\n );\n event WithdrawStake(address indexed delegator, uint256 unbondingLockId, uint256 amount, uint256 withdrawRound);\n event WithdrawFees(address indexed delegator, address recipient, uint256 amount);\n event EarningsClaimed(\n address indexed delegate,\n address indexed delegator,\n uint256 rewards,\n uint256 fees,\n uint256 startRound,\n uint256 endRound\n );\n\n // Deprecated events\n // These event signatures can be used to construct the appropriate topic hashes to filter for past logs corresponding\n // to these deprecated events.\n // event Bond(address indexed delegate, address indexed delegator);\n // event Unbond(address indexed delegate, address indexed delegator);\n // event WithdrawStake(address indexed delegator);\n // event TranscoderUpdate(address indexed transcoder, uint256 pendingRewardCut, uint256 pendingFeeShare, uint256 pendingPricePerSegment, bool registered);\n // event TranscoderEvicted(address indexed transcoder);\n // event TranscoderResigned(address indexed transcoder);\n\n // External functions\n function updateTranscoderWithFees(\n address _transcoder,\n uint256 _fees,\n uint256 _round\n ) external;\n\n function slashTranscoder(\n address _transcoder,\n address _finder,\n uint256 _slashAmount,\n uint256 _finderFee\n ) external;\n\n function setCurrentRoundTotalActiveStake() external;\n\n // Public functions\n function getTranscoderPoolSize() external view returns (uint256);\n\n function transcoderTotalStake(address _transcoder) external view returns (uint256);\n\n function isActiveTranscoder(address _transcoder) external view returns (bool);\n\n function getTotalBonded() external view returns (uint256);\n\n function nextRoundTotalActiveStake() external view returns (uint256);\n\n function getTranscoderEarningsPoolForRound(address _transcoder, uint256 _round)\n external\n view\n returns (\n uint256 totalStake,\n uint256 transcoderRewardCut,\n uint256 transcoderFeeShare,\n uint256 cumulativeRewardFactor,\n uint256 cumulativeFeeFactor\n );\n}\n" + }, + "contracts/libraries/SortedDoublyLL.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n/**\n * @title A sorted doubly linked list with nodes sorted in descending order. Optionally accepts insert position hints\n *\n * Given a new node with a `key`, a hint is of the form `(prevId, nextId)` s.t. `prevId` and `nextId` are adjacent in the list.\n * `prevId` is a node with a key >= `key` and `nextId` is a node with a key <= `key`. If the sender provides a hint that is a valid insert position\n * the insert operation is a constant time storage write. However, the provided hint in a given transaction might be a valid insert position, but if other transactions are included first, when\n * the given transaction is executed the provided hint may no longer be a valid insert position. For example, one of the nodes referenced might be removed or their keys may\n * be updated such that the the pair of nodes in the hint no longer represent a valid insert position. If one of the nodes in the hint becomes invalid, we still try to use the other\n * valid node as a starting point for finding the appropriate insert position. If both nodes in the hint become invalid, we use the head of the list as a starting point\n * to find the appropriate insert position.\n */\nlibrary SortedDoublyLL {\n using SafeMath for uint256;\n\n // Information for a node in the list\n struct Node {\n uint256 key; // Node's key used for sorting\n address nextId; // Id of next node (smaller key) in the list\n address prevId; // Id of previous node (larger key) in the list\n }\n\n // Information for the list\n struct Data {\n address head; // Head of the list. Also the node in the list with the largest key\n address tail; // Tail of the list. Also the node in the list with the smallest key\n uint256 maxSize; // Maximum size of the list\n uint256 size; // Current size of the list\n mapping(address => Node) nodes; // Track the corresponding ids for each node in the list\n }\n\n /**\n * @dev Set the maximum size of the list\n * @param _size Maximum size\n */\n function setMaxSize(Data storage self, uint256 _size) public {\n require(_size > self.maxSize, \"new max size must be greater than old max size\");\n\n self.maxSize = _size;\n }\n\n /**\n * @dev Add a node to the list\n * @param _id Node's id\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function insert(\n Data storage self,\n address _id,\n uint256 _key,\n address _prevId,\n address _nextId\n ) public {\n // List must not be full\n require(!isFull(self), \"list is full\");\n // List must not already contain node\n require(!contains(self, _id), \"node already in list\");\n // Node id must not be null\n require(_id != address(0), \"node id is null\");\n // Key must be non-zero\n require(_key > 0, \"key is zero\");\n\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (!validInsertPosition(self, _key, prevId, nextId)) {\n // Sender's hint was not a valid insert position\n // Use sender's hint to find a valid insert position\n (prevId, nextId) = findInsertPosition(self, _key, prevId, nextId);\n }\n\n self.nodes[_id].key = _key;\n\n if (prevId == address(0) && nextId == address(0)) {\n // Insert as head and tail\n self.head = _id;\n self.tail = _id;\n } else if (prevId == address(0)) {\n // Insert before `prevId` as the head\n self.nodes[_id].nextId = self.head;\n self.nodes[self.head].prevId = _id;\n self.head = _id;\n } else if (nextId == address(0)) {\n // Insert after `nextId` as the tail\n self.nodes[_id].prevId = self.tail;\n self.nodes[self.tail].nextId = _id;\n self.tail = _id;\n } else {\n // Insert at insert position between `prevId` and `nextId`\n self.nodes[_id].nextId = nextId;\n self.nodes[_id].prevId = prevId;\n self.nodes[prevId].nextId = _id;\n self.nodes[nextId].prevId = _id;\n }\n\n self.size = self.size.add(1);\n }\n\n /**\n * @dev Remove a node from the list\n * @param _id Node's id\n */\n function remove(Data storage self, address _id) public {\n // List must contain the node\n require(contains(self, _id), \"node not in list\");\n\n if (self.size > 1) {\n // List contains more than a single node\n if (_id == self.head) {\n // The removed node is the head\n // Set head to next node\n self.head = self.nodes[_id].nextId;\n // Set prev pointer of new head to null\n self.nodes[self.head].prevId = address(0);\n } else if (_id == self.tail) {\n // The removed node is the tail\n // Set tail to previous node\n self.tail = self.nodes[_id].prevId;\n // Set next pointer of new tail to null\n self.nodes[self.tail].nextId = address(0);\n } else {\n // The removed node is neither the head nor the tail\n // Set next pointer of previous node to the next node\n self.nodes[self.nodes[_id].prevId].nextId = self.nodes[_id].nextId;\n // Set prev pointer of next node to the previous node\n self.nodes[self.nodes[_id].nextId].prevId = self.nodes[_id].prevId;\n }\n } else {\n // List contains a single node\n // Set the head and tail to null\n self.head = address(0);\n self.tail = address(0);\n }\n\n delete self.nodes[_id];\n self.size = self.size.sub(1);\n }\n\n /**\n * @dev Update the key of a node in the list\n * @param _id Node's id\n * @param _newKey Node's new key\n * @param _prevId Id of previous node for the new insert position\n * @param _nextId Id of next node for the new insert position\n */\n function updateKey(\n Data storage self,\n address _id,\n uint256 _newKey,\n address _prevId,\n address _nextId\n ) public {\n // List must contain the node\n require(contains(self, _id), \"node not in list\");\n\n // Remove node from the list\n remove(self, _id);\n\n if (_newKey > 0) {\n // Insert node if it has a non-zero key\n insert(self, _id, _newKey, _prevId, _nextId);\n }\n }\n\n /**\n * @dev Checks if the list contains a node\n * @param _id Address of transcoder\n * @return true if '_id' is in list\n */\n function contains(Data storage self, address _id) public view returns (bool) {\n // List only contains non-zero keys, so if key is non-zero the node exists\n return self.nodes[_id].key > 0;\n }\n\n /**\n * @dev Checks if the list is full\n * @return true if list is full\n */\n function isFull(Data storage self) public view returns (bool) {\n return self.size == self.maxSize;\n }\n\n /**\n * @dev Checks if the list is empty\n * @return true if list is empty\n */\n function isEmpty(Data storage self) public view returns (bool) {\n return self.size == 0;\n }\n\n /**\n * @dev Returns the current size of the list\n * @return current size of the list\n */\n function getSize(Data storage self) public view returns (uint256) {\n return self.size;\n }\n\n /**\n * @dev Returns the maximum size of the list\n */\n function getMaxSize(Data storage self) public view returns (uint256) {\n return self.maxSize;\n }\n\n /**\n * @dev Returns the key of a node in the list\n * @param _id Node's id\n * @return key for node with '_id'\n */\n function getKey(Data storage self, address _id) public view returns (uint256) {\n return self.nodes[_id].key;\n }\n\n /**\n * @dev Returns the first node in the list (node with the largest key)\n * @return address for the head of the list\n */\n function getFirst(Data storage self) public view returns (address) {\n return self.head;\n }\n\n /**\n * @dev Returns the last node in the list (node with the smallest key)\n * @return address for the tail of the list\n */\n function getLast(Data storage self) public view returns (address) {\n return self.tail;\n }\n\n /**\n * @dev Returns the next node (with a smaller key) in the list for a given node\n * @param _id Node's id\n * @return address for the node following node in list with '_id'\n */\n function getNext(Data storage self, address _id) public view returns (address) {\n return self.nodes[_id].nextId;\n }\n\n /**\n * @dev Returns the previous node (with a larger key) in the list for a given node\n * @param _id Node's id\n * address for the node before node in list with '_id'\n */\n function getPrev(Data storage self, address _id) public view returns (address) {\n return self.nodes[_id].prevId;\n }\n\n /**\n * @dev Check if a pair of nodes is a valid insertion point for a new node with the given key\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n * @return if the insert position is valid\n */\n function validInsertPosition(\n Data storage self,\n uint256 _key,\n address _prevId,\n address _nextId\n ) public view returns (bool) {\n if (_prevId == address(0) && _nextId == address(0)) {\n // `(null, null)` is a valid insert position if the list is empty\n return isEmpty(self);\n } else if (_prevId == address(0)) {\n // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list\n return self.head == _nextId && _key >= self.nodes[_nextId].key;\n } else if (_nextId == address(0)) {\n // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list\n return self.tail == _prevId && _key <= self.nodes[_prevId].key;\n } else {\n // `(_prevId, _nextId)` is a valid insert position if they are adjacent nodes and `_key` falls between the two nodes' keys\n return\n self.nodes[_prevId].nextId == _nextId &&\n self.nodes[_prevId].key >= _key &&\n _key >= self.nodes[_nextId].key;\n }\n }\n\n /**\n * @dev Descend the list (larger keys to smaller keys) to find a valid insert position\n * @param _key Node's key\n * @param _startId Id of node to start ascending the list from\n */\n function descendList(\n Data storage self,\n uint256 _key,\n address _startId\n ) private view returns (address, address) {\n // If `_startId` is the head, check if the insert position is before the head\n if (self.head == _startId && _key >= self.nodes[_startId].key) {\n return (address(0), _startId);\n }\n\n address prevId = _startId;\n address nextId = self.nodes[prevId].nextId;\n\n // Descend the list until we reach the end or until we find a valid insert position\n while (prevId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {\n prevId = self.nodes[prevId].nextId;\n nextId = self.nodes[prevId].nextId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Ascend the list (smaller keys to larger keys) to find a valid insert position\n * @param _key Node's key\n * @param _startId Id of node to start descending the list from\n */\n function ascendList(\n Data storage self,\n uint256 _key,\n address _startId\n ) private view returns (address, address) {\n // If `_startId` is the tail, check if the insert position is after the tail\n if (self.tail == _startId && _key <= self.nodes[_startId].key) {\n return (_startId, address(0));\n }\n\n address nextId = _startId;\n address prevId = self.nodes[nextId].prevId;\n\n // Ascend the list until we reach the end or until we find a valid insertion point\n while (nextId != address(0) && !validInsertPosition(self, _key, prevId, nextId)) {\n nextId = self.nodes[nextId].prevId;\n prevId = self.nodes[nextId].prevId;\n }\n\n return (prevId, nextId);\n }\n\n /**\n * @dev Find the insert position for a new node with the given key\n * @param _key Node's key\n * @param _prevId Id of previous node for the insert position\n * @param _nextId Id of next node for the insert position\n */\n function findInsertPosition(\n Data storage self,\n uint256 _key,\n address _prevId,\n address _nextId\n ) private view returns (address, address) {\n address prevId = _prevId;\n address nextId = _nextId;\n\n if (prevId != address(0)) {\n if (!contains(self, prevId) || _key > self.nodes[prevId].key) {\n // `prevId` does not exist anymore or now has a smaller key than the given key\n prevId = address(0);\n }\n }\n\n if (nextId != address(0)) {\n if (!contains(self, nextId) || _key < self.nodes[nextId].key) {\n // `nextId` does not exist anymore or now has a larger key than the given key\n nextId = address(0);\n }\n }\n\n if (prevId == address(0) && nextId == address(0)) {\n // No hint - descend list starting from head\n return descendList(self, _key, self.head);\n } else if (prevId == address(0)) {\n // No `prevId` for hint - ascend list starting from `nextId`\n return ascendList(self, _key, nextId);\n } else if (nextId == address(0)) {\n // No `nextId` for hint - descend list starting from `prevId`\n return descendList(self, _key, prevId);\n } else {\n // Descend list starting from `prevId`\n return descendList(self, _key, prevId);\n }\n }\n}\n" + }, + "contracts/libraries/MathUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nlibrary MathUtils {\n using SafeMath for uint256;\n\n // Divisor used for representing percentages\n uint256 public constant PERC_DIVISOR = 1000000;\n\n /**\n * @dev Returns whether an amount is a valid percentage out of PERC_DIVISOR\n * @param _amount Amount that is supposed to be a percentage\n */\n function validPerc(uint256 _amount) internal pure returns (bool) {\n return _amount <= PERC_DIVISOR;\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage\n * @param _fracDenom Denominator of fraction representing the percentage\n */\n function percOf(\n uint256 _amount,\n uint256 _fracNum,\n uint256 _fracDenom\n ) internal pure returns (uint256) {\n return _amount.mul(percPoints(_fracNum, _fracDenom)).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction over PERC_DIVISOR\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage with PERC_DIVISOR as the denominator\n */\n function percOf(uint256 _amount, uint256 _fracNum) internal pure returns (uint256) {\n return _amount.mul(_fracNum).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage representation of a fraction\n * @param _fracNum Numerator of fraction represeting the percentage\n * @param _fracDenom Denominator of fraction represeting the percentage\n */\n function percPoints(uint256 _fracNum, uint256 _fracDenom) internal pure returns (uint256) {\n return _fracNum.mul(PERC_DIVISOR).div(_fracDenom);\n }\n}\n" + }, + "contracts/libraries/PreciseMathUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nlibrary PreciseMathUtils {\n using SafeMath for uint256;\n\n // Divisor used for representing percentages\n uint256 public constant PERC_DIVISOR = 10**27;\n\n /**\n * @dev Returns whether an amount is a valid percentage out of PERC_DIVISOR\n * @param _amount Amount that is supposed to be a percentage\n */\n function validPerc(uint256 _amount) internal pure returns (bool) {\n return _amount <= PERC_DIVISOR;\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage\n * @param _fracDenom Denominator of fraction representing the percentage\n */\n function percOf(\n uint256 _amount,\n uint256 _fracNum,\n uint256 _fracDenom\n ) internal pure returns (uint256) {\n return _amount.mul(percPoints(_fracNum, _fracDenom)).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction over PERC_DIVISOR\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage with PERC_DIVISOR as the denominator\n */\n function percOf(uint256 _amount, uint256 _fracNum) internal pure returns (uint256) {\n return _amount.mul(_fracNum).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage representation of a fraction\n * @param _fracNum Numerator of fraction represeting the percentage\n * @param _fracDenom Denominator of fraction represeting the percentage\n */\n function percPoints(uint256 _fracNum, uint256 _fracDenom) internal pure returns (uint256) {\n return _fracNum.mul(PERC_DIVISOR).div(_fracDenom);\n }\n}\n" + }, + "contracts/bonding/libraries/EarningsPool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../libraries/MathUtils.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n/**\n * @title EarningsPool\n * @dev Manages reward and fee pools for delegators and transcoders\n */\nlibrary EarningsPool {\n using SafeMath for uint256;\n\n struct Data {\n uint256 totalStake; // Transcoder's total stake during the earnings pool's round\n uint256 transcoderRewardCut; // Transcoder's reward cut during the earnings pool's round\n uint256 transcoderFeeShare; // Transcoder's fee share during the earnings pool's round\n // LIP-36 (https://github.com/livepeer/LIPs/blob/master/LIPs/LIP-36.md) fields\n // See EarningsPoolLIP36.sol\n uint256 cumulativeRewardFactor;\n uint256 cumulativeFeeFactor;\n }\n\n /**\n * @dev Sets transcoderRewardCut and transcoderFeeshare for an EarningsPool\n * @param earningsPool Storage pointer to EarningsPool struct\n * @param _rewardCut Reward cut of transcoder during the earnings pool's round\n * @param _feeShare Fee share of transcoder during the earnings pool's round\n */\n function setCommission(\n EarningsPool.Data storage earningsPool,\n uint256 _rewardCut,\n uint256 _feeShare\n ) internal {\n earningsPool.transcoderRewardCut = _rewardCut;\n earningsPool.transcoderFeeShare = _feeShare;\n }\n\n /**\n * @dev Sets totalStake for an EarningsPool\n * @param earningsPool Storage pointer to EarningsPool struct\n * @param _stake Total stake of the transcoder during the earnings pool's round\n */\n function setStake(EarningsPool.Data storage earningsPool, uint256 _stake) internal {\n earningsPool.totalStake = _stake;\n }\n}\n" + }, + "contracts/bonding/libraries/EarningsPoolLIP36.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./EarningsPool.sol\";\nimport \"../../libraries/PreciseMathUtils.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nlibrary EarningsPoolLIP36 {\n using SafeMath for uint256;\n\n /**\n * @notice Update the cumulative fee factor stored in an earnings pool with new fees\n * @param earningsPool Storage pointer to EarningsPools.Data struct\n * @param _prevEarningsPool In-memory EarningsPool.Data struct that stores the previous cumulative reward and fee factors\n * @param _fees Amount of new fees\n */\n function updateCumulativeFeeFactor(\n EarningsPool.Data storage earningsPool,\n EarningsPool.Data memory _prevEarningsPool,\n uint256 _fees\n ) internal {\n uint256 prevCumulativeFeeFactor = _prevEarningsPool.cumulativeFeeFactor;\n uint256 prevCumulativeRewardFactor = _prevEarningsPool.cumulativeRewardFactor != 0\n ? _prevEarningsPool.cumulativeRewardFactor\n : PreciseMathUtils.percPoints(1, 1);\n\n // Initialize the cumulativeFeeFactor when adding fees for the first time\n if (earningsPool.cumulativeFeeFactor == 0) {\n earningsPool.cumulativeFeeFactor = prevCumulativeFeeFactor.add(\n PreciseMathUtils.percOf(prevCumulativeRewardFactor, _fees, earningsPool.totalStake)\n );\n return;\n }\n\n earningsPool.cumulativeFeeFactor = earningsPool.cumulativeFeeFactor.add(\n PreciseMathUtils.percOf(prevCumulativeRewardFactor, _fees, earningsPool.totalStake)\n );\n }\n\n /**\n * @notice Update the cumulative reward factor stored in an earnings pool with new rewards\n * @param earningsPool Storage pointer to EarningsPool.Data struct\n * @param _prevEarningsPool Storage pointer to EarningsPool.Data struct that stores the previous cumulative reward factor\n * @param _rewards Amount of new rewards\n */\n function updateCumulativeRewardFactor(\n EarningsPool.Data storage earningsPool,\n EarningsPool.Data memory _prevEarningsPool,\n uint256 _rewards\n ) internal {\n uint256 prevCumulativeRewardFactor = _prevEarningsPool.cumulativeRewardFactor != 0\n ? _prevEarningsPool.cumulativeRewardFactor\n : PreciseMathUtils.percPoints(1, 1);\n\n earningsPool.cumulativeRewardFactor = prevCumulativeRewardFactor.add(\n PreciseMathUtils.percOf(prevCumulativeRewardFactor, _rewards, earningsPool.totalStake)\n );\n }\n\n /**\n * @notice Calculates a delegator's cumulative stake and fees using the LIP-36 earnings claiming algorithm.\n * @dev This internally calls {delegatorCumulativeStake} and {delegatorCumulativeFees} to calculate stake and fees.\n * @param _startPool The earning pool from the start round for the start cumulative factors. Normally this is the\n * earning pool from the {Delegator-lastClaimRound} round, as the round where `_stake` was measured.\n * @param _endPool The earning pool from the end round for the end cumulative factors\n * @param _stake The delegator stake at the start round, before earned rewards. Normally {Delegator-bondedAmount}.\n * @param _fees The delegator's initial fees before including earned fees\n * @return cStake , cFees where cStake is the delegator's cumulative stake including earned rewards and cFees is the\n * delegator's cumulative fees including earned fees\n */\n function delegatorCumulativeStakeAndFees(\n EarningsPool.Data memory _startPool,\n EarningsPool.Data memory _endPool,\n uint256 _stake,\n uint256 _fees\n ) internal pure returns (uint256 cStake, uint256 cFees) {\n cStake = delegatorCumulativeStake(_startPool, _endPool, _stake);\n cFees = delegatorCumulativeFees(_startPool, _endPool, _stake, _fees);\n }\n\n /**\n * @notice Calculates a delegator's cumulative stake using the LIP-36 earnings claiming algorithm.\n * @param _startPool The earning pool from the start round for the start cumulative factors. Normally this is the\n * earning pool from the {Delegator-lastClaimRound} round, as the round where `_stake` was measured.\n * @param _endPool The earning pool from the end round for the end cumulative factors.\n * @param _stake The delegator stake at the start round, before earned rewards. Normally {Delegator-bondedAmount}.\n * @return The delegator's cumulative stake including earned rewards.\n */\n function delegatorCumulativeStake(\n EarningsPool.Data memory _startPool,\n EarningsPool.Data memory _endPool,\n uint256 _stake\n ) internal pure returns (uint256) {\n // If the start cumulativeRewardFactor is 0 set the default value to PreciseMathUtils.percPoints(1, 1)\n if (_startPool.cumulativeRewardFactor == 0) {\n _startPool.cumulativeRewardFactor = PreciseMathUtils.percPoints(1, 1);\n }\n\n // If the end cumulativeRewardFactor is 0 set the default value to PreciseMathUtils.percPoints(1, 1)\n if (_endPool.cumulativeRewardFactor == 0) {\n _endPool.cumulativeRewardFactor = PreciseMathUtils.percPoints(1, 1);\n }\n\n return PreciseMathUtils.percOf(_stake, _endPool.cumulativeRewardFactor, _startPool.cumulativeRewardFactor);\n }\n\n /**\n * @notice Calculates a delegator's cumulative fees using the LIP-36 earnings claiming algorithm.\n * @param _startPool The earning pool from the start round for the start cumulative factors. Normally this is the\n * earning pool from the {Delegator-lastClaimRound} round, as the round where `_stake` was measured.\n * @param _endPool The earning pool from the end round for the end cumulative factors.\n * @param _stake The delegator stake at the start round, before earned rewards. Normally {Delegator-bondedAmount}.\n * @param _fees The delegator's initial fees before including earned fees.\n * @return The delegator's cumulative fees including earned fees.\n */\n function delegatorCumulativeFees(\n EarningsPool.Data memory _startPool,\n EarningsPool.Data memory _endPool,\n uint256 _stake,\n uint256 _fees\n ) internal pure returns (uint256) {\n // If the start cumulativeRewardFactor is 0 set the default value to PreciseMathUtils.percPoints(1, 1)\n if (_startPool.cumulativeRewardFactor == 0) {\n _startPool.cumulativeRewardFactor = PreciseMathUtils.percPoints(1, 1);\n }\n\n uint256 earnedFees = PreciseMathUtils.percOf(\n _stake,\n _endPool.cumulativeFeeFactor.sub(_startPool.cumulativeFeeFactor),\n _startPool.cumulativeRewardFactor\n );\n return _fees.add(earnedFees);\n }\n}\n" + }, + "contracts/token/ILivepeerToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ILivepeerToken is IERC20 {\n function mint(address _to, uint256 _amount) external;\n\n function burn(uint256 _amount) external;\n}\n" + }, + "contracts/token/IMinter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../IController.sol\";\n\n/**\n * @title Minter interface\n */\ninterface IMinter {\n // Events\n event SetCurrentRewardTokens(uint256 currentMintableTokens, uint256 currentInflation);\n\n // External functions\n function createReward(uint256 _fracNum, uint256 _fracDenom) external returns (uint256);\n\n function trustedTransferTokens(address _to, uint256 _amount) external;\n\n function trustedBurnTokens(uint256 _amount) external;\n\n function trustedWithdrawETH(address payable _to, uint256 _amount) external;\n\n function depositETH() external payable returns (bool);\n\n function setCurrentRewardTokens() external;\n\n function currentMintableTokens() external view returns (uint256);\n\n function currentMintedTokens() external view returns (uint256);\n\n // Public functions\n function getController() external view returns (IController);\n}\n" + }, + "contracts/rounds/IRoundsManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\n/**\n * @title RoundsManager interface\n */\ninterface IRoundsManager {\n // Events\n event NewRound(uint256 indexed round, bytes32 blockHash);\n\n // Deprecated events\n // These event signatures can be used to construct the appropriate topic hashes to filter for past logs corresponding\n // to these deprecated events.\n // event NewRound(uint256 round)\n\n // External functions\n function initializeRound() external;\n\n function lipUpgradeRound(uint256 _lip) external view returns (uint256);\n\n // Public functions\n function blockNum() external view returns (uint256);\n\n function blockHash(uint256 _block) external view returns (bytes32);\n\n function blockHashForRound(uint256 _round) external view returns (bytes32);\n\n function currentRound() external view returns (uint256);\n\n function currentRoundStartBlock() external view returns (uint256);\n\n function currentRoundInitialized() external view returns (bool);\n\n function currentRoundLocked() external view returns (bool);\n}\n" + }, + "contracts/snapshots/IMerkleSnapshot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IMerkleSnapshot {\n function verify(\n bytes32 _id,\n bytes32[] calldata _proof,\n bytes32 _leaf\n ) external view returns (bool);\n}\n" + }, + "contracts/bonding/IBondingVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../treasury/IVotes.sol\";\n\n/**\n * @title Interface for BondingVotes\n */\ninterface IBondingVotes is IVotes {\n error InvalidCaller(address caller, address required);\n error InvalidStartRound(uint256 checkpointRound, uint256 requiredRound);\n error FutureLastClaimRound(uint256 lastClaimRound, uint256 maxAllowed);\n error InvalidTotalStakeCheckpointRound(uint256 checkpointRound, uint256 requiredRound);\n\n error FutureLookup(uint256 queryRound, uint256 maxAllowed);\n error MissingEarningsPool(address transcoder, uint256 round);\n\n // Indicates that the called function is not supported in this contract and should be performed through the\n // BondingManager instead. This is mostly used for IVotes delegation methods which must be bonds instead.\n error MustCallBondingManager(string bondingManagerFunction);\n\n /**\n * @dev Emitted when a checkpoint results in changes to a delegator's `bondedAmount`. This complements the events\n * from IERC5805 by also supporting voting power for the delegators themselves, though requiring knowledge about our\n * specific reward-claiming protocol to calculate voting power based on this value.\n */\n event DelegatorBondedAmountChanged(\n address indexed delegate,\n uint256 previousBondedAmount,\n uint256 previousLastClaimRound,\n uint256 newBondedAmount,\n uint256 newLastClaimRound\n );\n\n // BondingManager hooks\n\n function checkpointBondingState(\n address _account,\n uint256 _startRound,\n uint256 _bondedAmount,\n address _delegateAddress,\n uint256 _delegatedAmount,\n uint256 _lastClaimRound,\n uint256 _lastRewardRound\n ) external;\n\n function checkpointTotalActiveStake(uint256 _totalStake, uint256 _round) external;\n\n // Historical stake access functions\n\n function hasCheckpoint(address _account) external view returns (bool);\n\n function getTotalActiveStakeAt(uint256 _round) external view returns (uint256);\n\n function getVotesAndDelegateAtRoundStart(address _account, uint256 _round)\n external\n view\n returns (uint256 amount, address delegateAddress);\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "contracts/Manager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./IManager.sol\";\nimport \"./IController.sol\";\n\ncontract Manager is IManager {\n // Controller that contract is registered with\n IController public controller;\n\n // Check if sender is controller\n modifier onlyController() {\n _onlyController();\n _;\n }\n\n // Check if sender is controller owner\n modifier onlyControllerOwner() {\n _onlyControllerOwner();\n _;\n }\n\n // Check if controller is not paused\n modifier whenSystemNotPaused() {\n _whenSystemNotPaused();\n _;\n }\n\n // Check if controller is paused\n modifier whenSystemPaused() {\n _whenSystemPaused();\n _;\n }\n\n constructor(address _controller) {\n controller = IController(_controller);\n }\n\n /**\n * @notice Set controller. Only callable by current controller\n * @param _controller Controller contract address\n */\n function setController(address _controller) external onlyController {\n controller = IController(_controller);\n\n emit SetController(_controller);\n }\n\n function _onlyController() private view {\n require(msg.sender == address(controller), \"caller must be Controller\");\n }\n\n function _onlyControllerOwner() private view {\n require(msg.sender == controller.owner(), \"caller must be Controller owner\");\n }\n\n function _whenSystemNotPaused() private view {\n require(!controller.paused(), \"system is paused\");\n }\n\n function _whenSystemPaused() private view {\n require(controller.paused(), \"system is not paused\");\n }\n}\n" + }, + "contracts/IManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ninterface IManager {\n event SetController(address controller);\n event ParameterUpdate(string param);\n\n function setController(address _controller) external;\n}\n" + }, + "contracts/IController.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./zeppelin/Pausable.sol\";\n\nabstract contract IController is Pausable {\n event SetContractInfo(bytes32 id, address contractAddress, bytes20 gitCommitHash);\n\n function setContractInfo(\n bytes32 _id,\n address _contractAddress,\n bytes20 _gitCommitHash\n ) external virtual;\n\n function updateController(bytes32 _id, address _controller) external virtual;\n\n function getContract(bytes32 _id) public view virtual returns (address);\n}\n" + }, + "contracts/zeppelin/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./Ownable.sol\";\n\n/**\n * @title Pausable\n * @dev Base contract which allows children to implement an emergency stop mechanism.\n */\ncontract Pausable is Ownable {\n event Pause();\n event Unpause();\n\n bool public paused;\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!paused);\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(paused);\n _;\n }\n\n /**\n * @dev called by the owner to pause, triggers stopped state\n */\n function pause() public onlyOwner whenNotPaused {\n paused = true;\n emit Pause();\n }\n\n /**\n * @dev called by the owner to unpause, returns to normal state\n */\n function unpause() public onlyOwner whenPaused {\n paused = false;\n emit Unpause();\n }\n}\n" + }, + "contracts/zeppelin/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\ncontract Ownable {\n address public owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n * account.\n */\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == owner);\n _;\n }\n\n /**\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\n * @param newOwner The address to transfer ownership to.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n require(newOwner != address(0));\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "contracts/treasury/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC5805Upgradeable.sol\";\n\ninterface IVotes is IERC5805Upgradeable {\n function totalSupply() external view returns (uint256);\n\n function delegatedAt(address account, uint256 timepoint) external returns (address);\n\n // ERC-20 metadata functions that improve compatibility with tools like Tally\n\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5805Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../governance/utils/IVotesUpgradeable.sol\";\nimport \"./IERC6372Upgradeable.sol\";\n\ninterface IERC5805Upgradeable is IERC6372Upgradeable, IVotesUpgradeable {}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\n * configured to use block numbers, this will return the value at the end of the corresponding block.\n */\n function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\n * configured to use block numbers, this will return the value at the end of the corresponding block.\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC6372Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC6372Upgradeable {\n /**\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\n */\n function clock() external view returns (uint48);\n\n /**\n * @dev Description of the clock\n */\n // solhint-disable-next-line func-name-mixedcase\n function CLOCK_MODE() external view returns (string memory);\n}\n" + }, + "contracts/token/Minter.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../Manager.sol\";\nimport \"./IMinter.sol\";\nimport \"./ILivepeerToken.sol\";\nimport \"../rounds/IRoundsManager.sol\";\nimport \"../bonding/IBondingManager.sol\";\nimport \"../libraries/MathUtilsV2.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\ninterface IL2LPTDataCache {\n function l1CirculatingSupply() external view returns (uint256);\n}\n\n/**\n * @title Minter\n * @dev Manages inflation rate and the minting of new tokens for each round of the Livepeer protocol\n */\ncontract Minter is Manager, IMinter {\n using SafeMath for uint256;\n\n // Per round inflation rate\n uint256 public inflation;\n // Change in inflation rate per round until the target bonding rate is achieved\n uint256 public inflationChange;\n // Target bonding rate\n uint256 public targetBondingRate;\n\n // Current number of mintable tokens. Reset every round\n uint256 public currentMintableTokens;\n // Current number of minted tokens. Reset every round\n uint256 public currentMintedTokens;\n\n // Checks if caller is BondingManager\n modifier onlyBondingManager() {\n require(msg.sender == controller.getContract(keccak256(\"BondingManager\")), \"msg.sender not BondingManager\");\n _;\n }\n\n // Checks if caller is RoundsManager\n modifier onlyRoundsManager() {\n require(msg.sender == controller.getContract(keccak256(\"RoundsManager\")), \"msg.sender not RoundsManager\");\n _;\n }\n\n // Checks if caller is either BondingManager or JobsManager\n modifier onlyBondingManagerOrJobsManager() {\n require(\n msg.sender == controller.getContract(keccak256(\"BondingManager\")) ||\n msg.sender == controller.getContract(keccak256(\"JobsManager\")),\n \"msg.sender not BondingManager or JobsManager\"\n );\n _;\n }\n\n // Checks if caller is either the currently registered Minter or JobsManager\n modifier onlyMinterOrJobsManager() {\n require(\n msg.sender == controller.getContract(keccak256(\"Minter\")) ||\n msg.sender == controller.getContract(keccak256(\"JobsManager\")),\n \"msg.sender not Minter or JobsManager\"\n );\n _;\n }\n\n /**\n * @notice Minter constructor\n * @param _inflation Base inflation rate as a percentage of current total token supply\n * @param _inflationChange Change in inflation rate each round (increase or decrease) if target bonding rate is not achieved\n * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply\n */\n constructor(\n address _controller,\n uint256 _inflation,\n uint256 _inflationChange,\n uint256 _targetBondingRate\n ) Manager(_controller) {\n // Inflation must be valid percentage\n require(MathUtils.validPerc(_inflation), \"_inflation is invalid percentage\");\n // Inflation change must be valid percentage\n require(MathUtils.validPerc(_inflationChange), \"_inflationChange is invalid percentage\");\n // Target bonding rate must be valid percentage\n require(MathUtils.validPerc(_targetBondingRate), \"_targetBondingRate is invalid percentage\");\n\n inflation = _inflation;\n inflationChange = _inflationChange;\n targetBondingRate = _targetBondingRate;\n }\n\n /**\n * @notice Set targetBondingRate. Only callable by Controller owner\n * @param _targetBondingRate Target bonding rate as a percentage of total bonded tokens / total token supply\n */\n function setTargetBondingRate(uint256 _targetBondingRate) external onlyControllerOwner {\n // Must be valid percentage\n require(MathUtils.validPerc(_targetBondingRate), \"_targetBondingRate is invalid percentage\");\n\n targetBondingRate = _targetBondingRate;\n\n emit ParameterUpdate(\"targetBondingRate\");\n }\n\n /**\n * @notice Set inflationChange. Only callable by Controller owner\n * @param _inflationChange Inflation change as a percentage of total token supply\n */\n function setInflationChange(uint256 _inflationChange) external onlyControllerOwner {\n // Must be valid percentage\n require(MathUtils.validPerc(_inflationChange), \"_inflationChange is invalid percentage\");\n\n inflationChange = _inflationChange;\n\n emit ParameterUpdate(\"inflationChange\");\n }\n\n /**\n * @notice Migrate to a new Minter by transferring the current Minter's LPT + ETH balance to the new Minter\n * @dev Only callable by Controller owner\n * @param _newMinter Address of new Minter\n */\n function migrateToNewMinter(IMinter _newMinter) external onlyControllerOwner {\n // New Minter cannot be the current Minter\n require(_newMinter != this, \"new Minter cannot be current Minter\");\n // Check for null address\n require(address(_newMinter) != address(0), \"new Minter cannot be null address\");\n\n IController newMinterController = _newMinter.getController();\n // New Minter must have same Controller as current Minter\n require(newMinterController == controller, \"new Minter Controller must be current Controller\");\n // New Minter's Controller must have the current Minter registered\n require(newMinterController.getContract(keccak256(\"Minter\")) == address(this), \"new Minter must be registered\");\n\n // Transfer current Minter's token balance to new Minter\n livepeerToken().transfer(address(_newMinter), livepeerToken().balanceOf(address(this)));\n // Transfer current Minter's ETH balance to new Minter\n _newMinter.depositETH{ value: address(this).balance }();\n }\n\n /**\n * @notice Create reward based on a fractional portion of the mintable tokens for the current round\n * @param _fracNum Numerator of fraction (active transcoder's stake)\n * @param _fracDenom Denominator of fraction (total active stake)\n */\n function createReward(uint256 _fracNum, uint256 _fracDenom)\n external\n onlyBondingManager\n whenSystemNotPaused\n returns (uint256)\n {\n // Compute and mint fraction of mintable tokens to include in reward\n uint256 mintAmount = MathUtils.percOf(currentMintableTokens, _fracNum, _fracDenom);\n // Update amount of minted tokens for round\n currentMintedTokens = currentMintedTokens.add(mintAmount);\n // Minted tokens must not exceed mintable tokens\n require(currentMintedTokens <= currentMintableTokens, \"minted tokens cannot exceed mintable tokens\");\n // Mint new tokens\n livepeerToken().mint(address(this), mintAmount);\n\n // Reward = minted tokens\n return mintAmount;\n }\n\n /**\n * @notice Transfer tokens to a receipient. Only callable by BondingManager - always trusts BondingManager\n * @param _to Recipient address\n * @param _amount Amount of tokens\n */\n function trustedTransferTokens(address _to, uint256 _amount) external onlyBondingManager whenSystemNotPaused {\n livepeerToken().transfer(_to, _amount);\n }\n\n /**\n * @notice Burn tokens. Only callable by BondingManager - always trusts BondingManager\n * @param _amount Amount of tokens to burn\n */\n function trustedBurnTokens(uint256 _amount) external onlyBondingManager whenSystemNotPaused {\n livepeerToken().burn(_amount);\n }\n\n /**\n * @notice Withdraw ETH to a recipient. Only callable by BondingManager or TicketBroker - always trusts these two contracts\n * @param _to Recipient address\n * @param _amount Amount of ETH\n */\n function trustedWithdrawETH(address payable _to, uint256 _amount)\n external\n onlyBondingManagerOrJobsManager\n whenSystemNotPaused\n {\n _to.transfer(_amount);\n }\n\n /**\n * @notice Deposit ETH to this contract. Only callable by the currently registered Minter or JobsManager\n */\n function depositETH() external payable onlyMinterOrJobsManager returns (bool) {\n return true;\n }\n\n /**\n * @notice Set inflation and mintable tokens for the round. Only callable by the RoundsManager\n */\n function setCurrentRewardTokens() external onlyRoundsManager whenSystemNotPaused {\n setInflation();\n\n // Set mintable tokens based upon current inflation and current total token supply\n currentMintableTokens = MathUtils.percOf(getGlobalTotalSupply(), inflation);\n currentMintedTokens = 0;\n\n emit SetCurrentRewardTokens(currentMintableTokens, inflation);\n }\n\n /**\n * @dev Returns Controller interface\n */\n function getController() public view returns (IController) {\n return controller;\n }\n\n /**\n * @notice Calculate and return global LPT total supply\n * @return Global LPT total supply\n */\n function getGlobalTotalSupply() public view returns (uint256) {\n // Global total supply = L2 total supply + L1 circulating supply\n return livepeerToken().totalSupply().add(l2LPTDataCache().l1CirculatingSupply());\n }\n\n /**\n * @dev Set inflation based upon the current bonding rate and target bonding rate\n */\n function setInflation() internal {\n uint256 currentBondingRate;\n uint256 totalSupply = getGlobalTotalSupply();\n\n if (totalSupply > 0) {\n uint256 totalBonded = bondingManager().getTotalBonded();\n currentBondingRate = MathUtils.percPoints(totalBonded, totalSupply);\n }\n\n if (currentBondingRate < targetBondingRate) {\n // Bonding rate is below the target - increase inflation\n inflation = inflation.add(inflationChange);\n } else if (currentBondingRate > targetBondingRate) {\n // Bonding rate is above the target - decrease inflation\n if (inflationChange > inflation) {\n inflation = 0;\n } else {\n inflation = inflation.sub(inflationChange);\n }\n }\n }\n\n /**\n * @dev Returns LivepeerToken interface\n */\n function livepeerToken() internal view returns (ILivepeerToken) {\n return ILivepeerToken(controller.getContract(keccak256(\"LivepeerToken\")));\n }\n\n /**\n * @dev Returns BondingManager interface\n */\n function bondingManager() internal view returns (IBondingManager) {\n return IBondingManager(controller.getContract(keccak256(\"BondingManager\")));\n }\n\n /**\n * @dev Returns L2LPTDataCache interface\n */\n function l2LPTDataCache() internal view returns (IL2LPTDataCache) {\n return IL2LPTDataCache(controller.getContract(keccak256(\"L2LPTDataCache\")));\n }\n}\n" + }, + "contracts/libraries/MathUtilsV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nlibrary MathUtils {\n using SafeMath for uint256;\n\n // Divisor used for representing percentages\n uint256 public constant PERC_DIVISOR = 1000000000;\n\n /**\n * @dev Returns whether an amount is a valid percentage out of PERC_DIVISOR\n * @param _amount Amount that is supposed to be a percentage\n */\n function validPerc(uint256 _amount) internal pure returns (bool) {\n return _amount <= PERC_DIVISOR;\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage\n * @param _fracDenom Denominator of fraction representing the percentage\n */\n function percOf(\n uint256 _amount,\n uint256 _fracNum,\n uint256 _fracDenom\n ) internal pure returns (uint256) {\n return _amount.mul(percPoints(_fracNum, _fracDenom)).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage of a value with the percentage represented by a fraction over PERC_DIVISOR\n * @param _amount Amount to take the percentage of\n * @param _fracNum Numerator of fraction representing the percentage with PERC_DIVISOR as the denominator\n */\n function percOf(uint256 _amount, uint256 _fracNum) internal pure returns (uint256) {\n return _amount.mul(_fracNum).div(PERC_DIVISOR);\n }\n\n /**\n * @dev Compute percentage representation of a fraction\n * @param _fracNum Numerator of fraction represeting the percentage\n * @param _fracDenom Denominator of fraction represeting the percentage\n */\n function percPoints(uint256 _fracNum, uint256 _fracDenom) internal pure returns (uint256) {\n return _fracNum.mul(PERC_DIVISOR).div(_fracDenom);\n }\n}\n" + }, + "contracts/test/TestMathUtilsV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../libraries/MathUtilsV2.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestMathUtilsV2 {\n function test_validPerc() public {\n Assert.equal(MathUtils.validPerc(50), true, \"50 should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(0), true, \"0 should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(1000000000), true, \"the max should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(1000000001), false, \"1 more than the max should not be valid percentage\");\n }\n\n function test_percOf1() public {\n Assert.equal(MathUtils.percOf(100, 3, 4), 75, \"3/4 of 100 should be 75\");\n Assert.equal(MathUtils.percOf(100, 7, 9), 77, \"7/9 of 100 should be 77\");\n }\n\n function test_percOf2() public {\n Assert.equal(MathUtils.percOf(100, 3), 0, \".0000003% of 100 is 0\");\n Assert.equal(MathUtils.percOf(1000000000, 1), 1, \".0000001% of 1000000000 is 1\");\n Assert.equal(MathUtils.percOf(100, 100000000), 10, \"10% of 100 is 10\");\n }\n\n function test_percPoints() public {\n Assert.equal(MathUtils.percPoints(3, 4), 750000000, \"3/4 should convert to valid percentage\");\n Assert.equal(MathUtils.percPoints(100, 300), 333333333, \"100/300 should convert to valid percentage\");\n }\n}\n" + }, + "contracts/test/helpers/truffle/Assert.sol": { + "content": "// This file taken from here: https://raw.githubusercontent.com/smartcontractproduction/sol-unit/master/contracts/src/Assertions.sol\n// It was renamed to Assert.sol by Tim Coulter. Refactored for solidity 0.5.0 by Cruz Molina.\n//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./AssertString.sol\";\nimport \"./AssertBytes32.sol\";\nimport \"./AssertAddress.sol\";\nimport \"./AssertBool.sol\";\nimport \"./AssertUint.sol\";\nimport \"./AssertInt.sol\";\nimport \"./AssertUintArray.sol\";\nimport \"./AssertIntArray.sol\";\nimport \"./AssertAddressArray.sol\";\n// import \"./AssertAddressPayableArray.sol\";\n// ^would require an oldAssert.sol (0.4.0) & a newAssert.sol (0.5.0)\nimport \"./AssertBytes32Array.sol\";\nimport \"./AssertBalance.sol\";\nimport \"./AssertGeneral.sol\";\n\n/*\n File: Assertions.slb\n\n Author: Andreas Olofsson (androlo1980@gmail.com)\n\n Library: Assertions\n\n Assertions for unit testing contracts. Tests are run with the\n \n unit-testing framework.\n\n (start code)\n contract ModAdder {\n\n function addMod(uint a, uint b, uint modulus) constant returns (uint sum) {\n if (modulus == 0)\n throw;\n return addmod(a, b, modulus);\n }\n\n }\n\n contract SomeTest {\n using Assertions for uint;\n\n function testAdd() {\n var adder = new ModAdder();\n adder.addMod(50, 66, 30).equal(26, \"addition returned the wrong sum\");\n }\n }\n (end)\n\n It is also possible to extend , to have all bindings (using) properly set up.\n\n (start code)\n\n contract SomeTest is Test {\n\n function testAdd() {\n var adder = new ModAdder();\n adder.addMod(50, 66, 30).equal(26, \"addition returned the wrong sum\");\n }\n }\n (end)\n*/\n\nlibrary Assert {\n // ************************************** general **************************************\n\n /*\n Function: fail()\n\n Mark the test as failed.\n\n Params:\n message (string) - A message associated with the failure.\n\n Returns:\n result (bool) - false.\n */\n function fail(string memory message) internal returns (bool result) {\n return AssertGeneral.fail(message);\n }\n\n // ************************************** strings **************************************\n\n /*\n Function: equal(string)\n\n Assert that two strings are equal.\n\n : _stringsEqual(A, B) == true\n\n Params:\n A (string) - The first string.\n B (string) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n string memory a,\n string memory b,\n string memory message\n ) internal returns (bool result) {\n return AssertString.equal(a, b, message);\n }\n\n /*\n Function: notEqual(string)\n\n Assert that two strings are not equal.\n\n : _stringsEqual(A, B) == false\n\n Params:\n A (string) - The first string.\n B (string) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n string memory a,\n string memory b,\n string memory message\n ) internal returns (bool result) {\n return AssertString.notEqual(a, b, message);\n }\n\n /*\n Function: isEmpty(string)\n\n Assert that a string is empty.\n\n : _stringsEqual(str, STRING_NULL) == true\n\n Params:\n str (string) - The string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isEmpty(string memory str, string memory message) internal returns (bool result) {\n return AssertString.isEmpty(str, message);\n }\n\n /*\n Function: isNotEmpty(string)\n\n Assert that a string is not empty.\n\n : _stringsEqual(str, STRING_NULL) == false\n\n Params:\n str (string) - The string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotEmpty(string memory str, string memory message) internal returns (bool result) {\n return AssertString.isNotEmpty(str, message);\n }\n\n // ************************************** bytes32 **************************************\n\n /*\n Function: equal(bytes32)\n\n Assert that two 'bytes32' are equal.\n\n : A == B\n\n Params:\n A (bytes32) - The first 'bytes32'.\n B (bytes32) - The second 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bytes32 a,\n bytes32 b,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32.equal(a, b, message);\n }\n\n /*\n Function: notEqual(bytes32)\n\n Assert that two 'bytes32' are not equal.\n\n : A != B\n\n Params:\n A (bytes32) - The first 'bytes32'.\n B (bytes32) - The second 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bytes32 a,\n bytes32 b,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32.notEqual(a, b, message);\n }\n\n /*\n Function: isZero(bytes32)\n\n Assert that a 'bytes32' is zero.\n\n : bts == BYTES32_NULL\n\n Params:\n bts (bytes32) - The 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(bytes32 bts, string memory message) internal returns (bool result) {\n return AssertBytes32.isZero(bts, message);\n }\n\n /*\n Function: isNotZero(bytes32)\n\n Assert that a 'bytes32' is not zero.\n\n : bts != BYTES32_NULL\n\n Params:\n bts (bytes32) - The 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(bytes32 bts, string memory message) internal returns (bool result) {\n return AssertBytes32.isNotZero(bts, message);\n }\n\n // ************************************** address **************************************\n\n /*\n Function: equal(address)\n\n Assert that two addresses are equal.\n\n : A == B\n\n Params:\n A (address) - The first address.\n B (address) - The second address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n address a,\n address b,\n string memory message\n ) internal returns (bool result) {\n return AssertAddress.equal(a, b, message);\n }\n\n /*\n Function: notEqual(address)\n\n Assert that two addresses are not equal.\n\n : A != B\n\n Params:\n A (address) - The first address.\n B (address) - The second address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n address a,\n address b,\n string memory message\n ) internal returns (bool result) {\n return AssertAddress.notEqual(a, b, message);\n }\n\n /*\n Function: isZero(address)\n\n Assert that an address is zero.\n\n : addr == ADDRESS_NULL\n\n Params:\n addr (address) - The address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(address addr, string memory message) internal returns (bool result) {\n return AssertAddress.isZero(addr, message);\n }\n\n /*\n Function: isNotZero(address)\n\n Assert that an address is not zero.\n\n : addr != ADDRESS_NULL\n\n Params:\n addr (address) - The address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(address addr, string memory message) internal returns (bool result) {\n return AssertAddress.isNotZero(addr, message);\n }\n\n // ************************************** bool **************************************\n\n /*\n Function: isTrue\n\n Assert that a boolean is 'true'.\n\n : b == true\n\n Params:\n b (bool) - The boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isTrue(bool b, string memory message) internal returns (bool result) {\n return AssertBool.isTrue(b, message);\n }\n\n /*\n Function: isFalse\n\n Assert that a boolean is 'false'.\n\n : b == false\n\n Params:\n b (bool) - The boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isFalse(bool b, string memory message) internal returns (bool result) {\n return AssertBool.isFalse(b, message);\n }\n\n /*\n Function: equal(bool)\n\n Assert that two booleans are equal.\n\n : A == B\n\n Params:\n A (bool) - The first boolean.\n B (bool) - The second boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bool a,\n bool b,\n string memory message\n ) internal returns (bool result) {\n return AssertBool.equal(a, b, message);\n }\n\n /*\n Function: notEqual(bool)\n\n Assert that two booleans are not equal.\n\n : A != B\n\n Params:\n A (bool) - The first boolean.\n B (bool) - The second boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bool a,\n bool b,\n string memory message\n ) internal returns (bool result) {\n return AssertBool.notEqual(a, b, message);\n }\n\n // ************************************** uint **************************************\n\n /*\n Function: equal(uint)\n\n Assert that two (256 bit) unsigned integers are equal.\n\n : A == B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.equal(a, b, message);\n }\n\n /*\n Function: notEqual(uint)\n\n Assert that two (256 bit) unsigned integers are not equal.\n\n : A != B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.notEqual(a, b, message);\n }\n\n /*\n Function: isAbove(uint)\n\n Assert that the uint 'A' is greater than the uint 'B'.\n\n : A > B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAbove(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.isAbove(a, b, message);\n }\n\n /*\n Function: isAtLeast(uint)\n\n Assert that the uint 'A' is greater than or equal to the uint 'B'.\n\n : A >= B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtLeast(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.isAtLeast(a, b, message);\n }\n\n /*\n Function: isBelow(uint)\n\n Assert that the uint 'A' is lesser than the uint 'B'.\n\n : A < B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isBelow(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.isBelow(a, b, message);\n }\n\n /*\n Function: isAtMost(uint)\n\n Assert that the uint 'A' is lesser than or equal to the uint 'B'.\n\n : A <= B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtMost(\n uint256 a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertUint.isAtMost(a, b, message);\n }\n\n /*\n Function: isZero(uint)\n\n Assert that a (256 bit) unsigned integer is 0.\n\n : number == 0\n\n Params:\n number (uint) - The uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(uint256 number, string memory message) internal returns (bool result) {\n return AssertUint.isZero(number, message);\n }\n\n /*\n Function: isNotZero(uint)\n\n Assert that a (256 bit) unsigned integer is not 0.\n\n : number != 0\n\n Params:\n number (uint) - The uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(uint256 number, string memory message) internal returns (bool result) {\n return AssertUint.isNotZero(number, message);\n }\n\n // ************************************** int **************************************\n\n /*\n Function: equal(int)\n\n Assert that two (256 bit) signed integers are equal.\n\n : A == B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.equal(a, b, message);\n }\n\n /*\n Function: notEqual(int)\n\n Assert that two (256 bit) signed integers are not equal.\n\n : A != B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.notEqual(a, b, message);\n }\n\n /*\n Function: isAbove(int)\n\n Assert that the int 'A' is greater than the int 'B'.\n\n : A > B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAbove(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.isAbove(a, b, message);\n }\n\n /*\n Function: isAtLeast(int)\n\n Assert that the int 'A' is greater than or equal to the int 'B'.\n\n : A >= B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtLeast(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.isAtLeast(a, b, message);\n }\n\n /*\n Function: isBelow(int)\n\n Assert that the int 'A' is lesser than the int 'B'.\n\n : A < B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isBelow(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.isBelow(a, b, message);\n }\n\n /*\n Function: isAtMost(int)\n\n Assert that the int 'A' is lesser than or equal to the int 'B'.\n\n : A <= B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtMost(\n int256 a,\n int256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertInt.isAtMost(a, b, message);\n }\n\n /*\n Function: isZero(int)\n\n Assert that a (256 bit) signed integer is 0.\n\n : number == 0\n\n Params:\n number (int) - The int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(int256 number, string memory message) internal returns (bool result) {\n return AssertInt.isZero(number, message);\n }\n\n /*\n Function: isNotZero(int)\n\n Assert that a (256 bit) signed integer is not 0.\n\n : number != 0\n\n Params:\n number (int) - The int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(int256 number, string memory message) internal returns (bool result) {\n return AssertInt.isNotZero(number, message);\n }\n\n // ************************************** uint[] **************************************\n\n /*\n Function: equal(uint[])\n\n Assert that two 'uint[ ]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (uint[]) - The first array.\n B (uint[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n uint256[] memory arrA,\n uint256[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertUintArray.equal(arrA, arrB, message);\n }\n\n /*\n Function: notEqual(uint[])\n\n Assert that two 'uint[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (uint[]) - The first string.\n B (uint[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n uint256[] memory arrA,\n uint256[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertUintArray.notEqual(arrA, arrB, message);\n }\n\n /*\n Function: lengthEqual(uint[])\n\n Assert that the length of a 'uint[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (uint[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n uint256[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertUintArray.lengthEqual(arr, length, message);\n }\n\n /*\n Function: lengthNotEqual(uint[])\n\n Assert that the length of a 'uint[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (uint[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n uint256[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertUintArray.lengthNotEqual(arr, length, message);\n }\n\n // ************************************** int[] **************************************\n\n /*\n Function: equal(int[])\n\n Assert that two 'int[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (int[]) - The first array.\n B (int[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n int256[] memory arrA,\n int256[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertIntArray.equal(arrA, arrB, message);\n }\n\n /*\n Function: notEqual(int[])\n\n Assert that two 'int[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (int[]) - The first string.\n B (int[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n int256[] memory arrA,\n int256[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertIntArray.notEqual(arrA, arrB, message);\n }\n\n /*\n Function: lengthEqual(int[])\n\n Assert that the length of an 'int[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (int[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n int256[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertIntArray.lengthEqual(arr, length, message);\n }\n\n /*\n Function: lengthNotEqual(int[])\n\n Assert that the length of an 'int[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (int[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n int256[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertIntArray.lengthNotEqual(arr, length, message);\n }\n\n // ************************************** address[] **************************************\n\n /*\n Function: equal(address[])\n\n Assert that two 'address[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (address[]) - The first array.\n B (address[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n address[] memory arrA,\n address[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertAddressArray.equal(arrA, arrB, message);\n }\n\n /*\n Function: notEqual(address[])\n\n Assert that two 'address[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (address[]) - The first string.\n B (address[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n address[] memory arrA,\n address[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertAddressArray.notEqual(arrA, arrB, message);\n }\n\n /*\n Function: lengthEqual(address[])\n\n Assert that the length of an 'address[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (address[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n address[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertAddressArray.lengthEqual(arr, length, message);\n }\n\n /*\n Function: lengthNotEqual(address[])\n\n Assert that the length of an 'address[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (address[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n address[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertAddressArray.lengthNotEqual(arr, length, message);\n }\n\n // ************************************** address payable[] **************************************\n\n /*\n Function: equal(address payable[])\n\n Assert that two 'address payable[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (address payable[]) - The first array.\n B (address payable[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n // function equal(address payable[] memory arrA, address payable[] memory arrB, string memory message) internal returns (bool result) {\n // return AssertAddressPayableArray.equal(arrA, arrB, message);\n // }\n\n /*\n Function: notEqual(address payable[])\n\n Assert that two 'address payable[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (address payable[]) - The first string.\n B (address payable[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n // function notEqual(address payable[] memory arrA, address payable[] memory arrB, string memory message) internal returns (bool result) {\n // return AssertAddressPayableArray.notEqual(arrA, arrB, message);\n // }\n\n /*\n Function: lengthEqual(address payable[])\n\n Assert that the length of an 'address payable[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (address payable[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n // function lengthEqual(address payable[] memory arr, uint length, string memory message) internal returns (bool result) {\n // return AssertAddressPayableArray.lengthEqual(arr, length, message);\n // }\n\n /*\n Function: lengthNotEqual(address payable[])\n\n Assert that the length of an 'address payable[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (address payable[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n // function lengthNotEqual(address payable[] memory arr, uint length, string memory message) internal returns (bool result) {\n // return AssertAddressPayableArray.lengthNotEqual(arr, length, message);\n // }\n\n // ************************************** bytes32[] **************************************\n\n /*\n Function: equal(bytes32[])\n\n Assert that two 'bytes32[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (bytes32[]) - The first array.\n B (bytes32[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bytes32[] memory arrA,\n bytes32[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32Array.equal(arrA, arrB, message);\n }\n\n /*\n Function: notEqual(bytes32[])\n\n Assert that two 'bytes32[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (bytes32[]) - The first string.\n B (bytes32[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bytes32[] memory arrA,\n bytes32[] memory arrB,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32Array.notEqual(arrA, arrB, message);\n }\n\n /*\n Function: lengthEqual(bytes32[])\n\n Assert that the length of an 'bytes32[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (bytes32[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n bytes32[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32Array.lengthEqual(arr, length, message);\n }\n\n /*\n Function: lengthNotEqual(bytes32[])\n\n Assert that the length of an 'bytes32[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (bytes32[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n bytes32[] memory arr,\n uint256 length,\n string memory message\n ) internal returns (bool result) {\n return AssertBytes32Array.lengthNotEqual(arr, length, message);\n }\n\n // ************************************** balances **************************************\n\n /*\n Function: balanceEqual\n\n Assert that the balance of an account 'A' is equal to a given number 'b'.\n\n : A.balance = b\n\n Params:\n A (address) - The first address.\n b (uint) - The balance.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceEqual(\n address a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertBalance.balanceEqual(a, b, message);\n }\n\n /*\n Function: balanceNotEqual\n\n Assert that the balance of an account 'A' is not equal to a given number 'b'.\n\n : A.balance != b\n\n Params:\n A (address) - The first address.\n b (uint) - The balance.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceNotEqual(\n address a,\n uint256 b,\n string memory message\n ) internal returns (bool result) {\n return AssertBalance.balanceNotEqual(a, b, message);\n }\n\n /*\n Function: balanceIsZero\n\n Assert that the balance of an account 'A' is zero.\n\n : A.balance == 0\n\n Params:\n A (address) - The first address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceIsZero(address a, string memory message) internal returns (bool result) {\n return AssertBalance.balanceIsZero(a, message);\n }\n\n /*\n Function: balanceIsNotZero\n\n Assert that the balance of an account 'A' is not zero.\n\n : A.balance != 0\n\n Params:\n A (address) - The first address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceIsNotZero(address a, string memory message) internal returns (bool result) {\n return AssertBalance.balanceIsNotZero(a, message);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertString.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertString {\n // Constant: STRING_NULL\n // The null string: \"\"\n string constant STRING_NULL = \"\";\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** strings **************************************\n\n /*\n Function: equal(string)\n\n Assert that two strings are equal.\n\n : _stringsEqual(A, B) == true\n\n Params:\n A (string) - The first string.\n B (string) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n string memory a,\n string memory b,\n string memory message\n ) public returns (bool result) {\n result = _stringsEqual(a, b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: notEqual(string)\n\n Assert that two strings are not equal.\n\n : _stringsEqual(A, B) == false\n\n Params:\n A (string) - The first string.\n B (string) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n string memory a,\n string memory b,\n string memory message\n ) public returns (bool result) {\n result = !_stringsEqual(a, b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isEmpty(string)\n\n Assert that a string is empty.\n\n : _stringsEqual(str, STRING_NULL) == true\n\n Params:\n str (string) - The string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isEmpty(string memory str, string memory message) public returns (bool result) {\n result = _stringsEqual(str, STRING_NULL);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(str, \"Tested\"), message));\n }\n\n /*\n Function: isNotEmpty(string)\n\n Assert that a string is not empty.\n\n : _stringsEqual(str, STRING_NULL) == false\n\n Params:\n str (string) - The string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotEmpty(string memory str, string memory message) public returns (bool result) {\n result = !_stringsEqual(str, STRING_NULL);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(str, \"Tested\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _stringsEqual\n\n Compares two strings. Taken from the StringUtils contract in the Ethereum Dapp-bin\n (https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol).\n\n Params:\n a (string) - The first string.\n b (string) - The second string.\n\n Returns:\n result (bool) - 'true' if the strings are equal, otherwise 'false'.\n */\n function _stringsEqual(string memory a, string memory b) internal pure returns (bool result) {\n bytes memory ba = bytes(a);\n bytes memory bb = bytes(b);\n\n if (ba.length != bb.length) return false;\n for (uint256 i = 0; i < ba.length; i++) {\n if (ba[i] != bb[i]) return false;\n }\n return true;\n }\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _appendTagged(string)\n\n Append a tagged value to a string.\n\n Params:\n tagged (string) - The tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged)\"\n */\n function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {\n bytes memory taggedB = bytes(tagged);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 tl = taggedB.length;\n\n bytes memory newB = new bytes(sl + tl + 3);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < tl; i++) newB[j++] = taggedB[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertBytes32.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertBytes32 {\n // Constant: BYTES32_NULL\n // The null bytes32: 0\n bytes32 constant BYTES32_NULL = 0x0;\n\n bytes1 constant MINUS = bytes1(\"-\");\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** bytes32 **************************************\n\n /*\n Function: equal(bytes32)\n\n Assert that two 'bytes32' are equal.\n\n : A == B\n\n Params:\n A (bytes32) - The first 'bytes32'.\n B (bytes32) - The second 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bytes32 a,\n bytes32 b,\n string memory message\n ) public returns (bool result) {\n result = (a == b);\n _report(result, message);\n }\n\n /*\n Function: notEqual(bytes32)\n\n Assert that two 'bytes32' are not equal.\n\n : A != B\n\n Params:\n A (bytes32) - The first 'bytes32'.\n B (bytes32) - The second 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bytes32 a,\n bytes32 b,\n string memory message\n ) public returns (bool result) {\n result = (a != b);\n _report(result, message);\n }\n\n /*\n Function: isZero(bytes32)\n\n Assert that a 'bytes32' is zero.\n\n : bts == BYTES32_NULL\n\n Params:\n bts (bytes32) - The 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(bytes32 bts, string memory message) public returns (bool result) {\n result = (bts == BYTES32_NULL);\n _report(result, message);\n }\n\n /*\n Function: isNotZero(bytes32)\n\n Assert that a 'bytes32' is not zero.\n\n : bts != BYTES32_NULL\n\n Params:\n bts (bytes32) - The 'bytes32'.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(bytes32 bts, string memory message) public returns (bool result) {\n result = (bts != BYTES32_NULL);\n _report(result, message);\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertAddress.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertAddress {\n // Constant: ADDRESS_NULL\n // The null address: 0\n address constant ADDRESS_NULL = 0x0000000000000000000000000000000000000000;\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** address **************************************\n\n /*\n Function: equal(address)\n\n Assert that two addresses are equal.\n\n : A == B\n\n Params:\n A (address) - The first address.\n B (address) - The second address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n address a,\n address b,\n string memory message\n ) public returns (bool result) {\n result = (a == b);\n _report(result, message);\n }\n\n /*\n Function: notEqual(address)\n\n Assert that two addresses are not equal.\n\n : A != B\n\n Params:\n A (address) - The first address.\n B (address) - The second address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n address a,\n address b,\n string memory message\n ) public returns (bool result) {\n result = (a != b);\n _report(result, message);\n }\n\n /*\n Function: isZero(address)\n\n Assert that an address is zero.\n\n : addr == ADDRESS_NULL\n\n Params:\n addr (address) - The address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(address addr, string memory message) public returns (bool result) {\n result = (addr == ADDRESS_NULL);\n _report(result, message);\n }\n\n /*\n Function: isNotZero(address)\n\n Assert that an address is not zero.\n\n : addr != ADDRESS_NULL\n\n Params:\n addr (address) - The address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(address addr, string memory message) public returns (bool result) {\n result = (addr != ADDRESS_NULL);\n _report(result, message);\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertBool.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertBool {\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** bool **************************************\n\n /*\n Function: isTrue\n\n Assert that a boolean is 'true'.\n\n : b == true\n\n Params:\n b (bool) - The boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isTrue(bool b, string memory message) public returns (bool result) {\n result = b;\n _report(result, message);\n }\n\n /*\n Function: isFalse\n\n Assert that a boolean is 'false'.\n\n : b == false\n\n Params:\n b (bool) - The boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isFalse(bool b, string memory message) public returns (bool result) {\n result = !b;\n _report(result, message);\n }\n\n /*\n Function: equal(bool)\n\n Assert that two booleans are equal.\n\n : A == B\n\n Params:\n A (bool) - The first boolean.\n B (bool) - The second boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bool a,\n bool b,\n string memory message\n ) public returns (bool result) {\n result = (a == b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: notEqual(bool)\n\n Assert that two booleans are not equal.\n\n : A != B\n\n Params:\n A (bool) - The first boolean.\n B (bool) - The second boolean.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bool a,\n bool b,\n string memory message\n ) public returns (bool result) {\n result = (a != b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _ltoa\n\n Convert an boolean to a string.\n\n Params:\n val (bool) - The boolean.\n\n Returns:\n result (string) - \"true\" if true, \"false\" if false.\n */\n function _ltoa(bool val) internal pure returns (string memory) {\n bytes memory b;\n if (val) {\n b = new bytes(4);\n b[0] = \"t\";\n b[1] = \"r\";\n b[2] = \"u\";\n b[3] = \"e\";\n return string(b);\n } else {\n b = new bytes(5);\n b[0] = \"f\";\n b[1] = \"a\";\n b[2] = \"l\";\n b[3] = \"s\";\n b[4] = \"e\";\n return string(b);\n }\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(bool)\n\n Add a tag to a boolean.\n\n Params:\n value (bool) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _ltoa(value)\"\n */\n function _tag(bool value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _ltoa(value);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertUint.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertUint {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** uint **************************************\n\n /*\n Function: equal(uint)\n\n Assert that two (256 bit) unsigned integers are equal.\n\n : A == B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a == b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: notEqual(uint)\n\n Assert that two (256 bit) unsigned integers are not equal.\n\n : A != B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a != b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAbove(uint)\n\n Assert that the uint 'A' is greater than the uint 'B'.\n\n : A > B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAbove(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a > b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAtLeast(uint)\n\n Assert that the uint 'A' is greater than or equal to the uint 'B'.\n\n : A >= B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtLeast(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a >= b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isBelow(uint)\n\n Assert that the uint 'A' is lesser than the uint 'B'.\n\n : A < B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isBelow(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a < b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAtMost(uint)\n\n Assert that the uint 'A' is lesser than or equal to the uint 'B'.\n\n : A <= B\n\n Params:\n A (uint) - The first uint.\n B (uint) - The second uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtMost(\n uint256 a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a <= b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isZero(uint)\n\n Assert that a (256 bit) unsigned integer is 0.\n\n : number == 0\n\n Params:\n number (uint) - The uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(uint256 number, string memory message) public returns (bool result) {\n result = (number == 0);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(number, \"Tested\"), message));\n }\n\n /*\n Function: isNotZero(uint)\n\n Assert that a (256 bit) unsigned integer is not 0.\n\n : number != 0\n\n Params:\n number (uint) - The uint.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(uint256 number, string memory message) public returns (bool result) {\n result = (number != 0);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(number, \"Tested\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _utoa(uint)\n\n Convert an unsigned integer to a string.\n\n Params:\n n (uint) - The unsigned integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n\n Returns:\n result (string) - The resulting string.\n */\n function _utoa(uint256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n while (n > 0) {\n bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.\n n /= radix;\n }\n // Reverse\n bytes memory rev = new bytes(i);\n for (uint256 j = 0; j < i; j++) rev[j] = bts[i - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(uint)\n\n Add a tag to an uint.\n\n Params:\n value (uint) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _utoa(value)\"\n */\n function _tag(uint256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _utoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string)\n\n Append a tagged value to a string.\n\n Params:\n tagged (string) - The tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged)\"\n */\n function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {\n bytes memory taggedB = bytes(tagged);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 tl = taggedB.length;\n\n bytes memory newB = new bytes(sl + tl + 3);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < tl; i++) newB[j++] = taggedB[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertInt.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertInt {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n\n bytes1 constant MINUS = bytes1(\"-\");\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** int **************************************\n\n /*\n Function: equal(int)\n\n Assert that two (256 bit) signed integers are equal.\n\n : A == B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a == b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: notEqual(int)\n\n Assert that two (256 bit) signed integers are not equal.\n\n : A != B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a != b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAbove(int)\n\n Assert that the int 'A' is greater than the int 'B'.\n\n : A > B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAbove(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a > b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAtLeast(int)\n\n Assert that the int 'A' is greater than or equal to the int 'B'.\n\n : A >= B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtLeast(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a >= b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isBelow(int)\n\n Assert that the int 'A' is lesser than the int 'B'.\n\n : A < B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isBelow(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a < b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isAtMost(int)\n\n Assert that the int 'A' is lesser than or equal to the int 'B'.\n\n : A <= B\n\n Params:\n A (int) - The first int.\n B (int) - The second int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isAtMost(\n int256 a,\n int256 b,\n string memory message\n ) public returns (bool result) {\n result = (a <= b);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(a, \"Tested\"), _tag(b, \"Against\"), message));\n }\n\n /*\n Function: isZero(int)\n\n Assert that a (256 bit) signed integer is 0.\n\n : number == 0\n\n Params:\n number (int) - The int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isZero(int256 number, string memory message) public returns (bool result) {\n result = (number == 0);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(number, \"Tested\"), message));\n }\n\n /*\n Function: isNotZero(int)\n\n Assert that a (256 bit) signed integer is not 0.\n\n : number != 0\n\n Params:\n number (int) - The int.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function isNotZero(int256 number, string memory message) public returns (bool result) {\n result = (number != 0);\n if (result) _report(result, message);\n else _report(result, _appendTagged(_tag(number, \"Tested\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _itoa\n Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. \"-54\".\n Params:\n n (int) - The integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n Returns:\n result (string) - The resulting string.\n */\n function _itoa(int256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n bool neg = false;\n if (n < 0) {\n n = -n;\n neg = true;\n }\n while (n > 0) {\n bts[i++] = _utoa(uint8(uint256(n) % radix)); // Turn it to ascii.\n n = int256(uint256(n) / radix);\n }\n // Reverse\n uint256 size = i;\n uint256 j = 0;\n bytes memory rev;\n if (neg) {\n size++;\n j = 1;\n rev = new bytes(size);\n rev[0] = MINUS;\n } else rev = new bytes(size);\n\n for (; j < size; j++) rev[j] = bts[size - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(int)\n\n Add a tag to an int.\n\n Params:\n value (int) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _itoa(value)\"\n */\n function _tag(int256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _itoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string)\n\n Append a tagged value to a string.\n\n Params:\n tagged (string) - The tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged)\"\n */\n function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {\n bytes memory taggedB = bytes(tagged);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 tl = taggedB.length;\n\n bytes memory newB = new bytes(sl + tl + 3);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < tl; i++) newB[j++] = taggedB[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertUintArray.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertUintArray {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** uint[] **************************************\n\n /*\n Function: equal(uint[])\n\n Assert that two 'uint[ ]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (uint[]) - The first array.\n B (uint[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n uint256[] memory arrA,\n uint256[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n _report(result, message);\n }\n\n /*\n Function: notEqual(uint[])\n\n Assert that two 'uint[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (uint[]) - The first string.\n B (uint[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n uint256[] memory arrA,\n uint256[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n result = !result;\n _report(result, message);\n }\n\n /*\n Function: lengthEqual(uint[])\n\n Assert that the length of a 'uint[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (uint[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n uint256[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength == length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /*\n Function: lengthNotEqual(uint[])\n\n Assert that the length of a 'uint[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (uint[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n uint256[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength != arr.length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _utoa(uint)\n\n Convert an unsigned integer to a string.\n\n Params:\n n (uint) - The unsigned integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n\n Returns:\n result (string) - The resulting string.\n */\n function _utoa(uint256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n while (n > 0) {\n bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.\n n /= radix;\n }\n // Reverse\n bytes memory rev = new bytes(i);\n for (uint256 j = 0; j < i; j++) rev[j] = bts[i - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(uint)\n\n Add a tag to an uint.\n\n Params:\n value (uint) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _utoa(value)\"\n */\n function _tag(uint256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _utoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string)\n\n Append a tagged value to a string.\n\n Params:\n tagged (string) - The tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged)\"\n */\n function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {\n bytes memory taggedB = bytes(tagged);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 tl = taggedB.length;\n\n bytes memory newB = new bytes(sl + tl + 3);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < tl; i++) newB[j++] = taggedB[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertIntArray.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertIntArray {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n\n bytes1 constant MINUS = bytes1(\"-\");\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** int[] **************************************\n\n /*\n Function: equal(int[])\n\n Assert that two 'int[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (int[]) - The first array.\n B (int[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n int256[] memory arrA,\n int256[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n _report(result, message);\n }\n\n /*\n Function: notEqual(int[])\n\n Assert that two 'int[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (int[]) - The first string.\n B (int[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n int256[] memory arrA,\n int256[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n result = !result;\n _report(result, message);\n }\n\n /*\n Function: lengthEqual(int[])\n\n Assert that the length of an 'int[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (int[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n int256[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength == length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /*\n Function: lengthNotEqual(int[])\n\n Assert that the length of an 'int[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (int[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n int256[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength != arr.length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _itoa\n Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. \"-54\".\n Params:\n n (int) - The integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n Returns:\n result (string) - The resulting string.\n */\n function _itoa(int256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n bool neg = false;\n if (n < 0) {\n n = -n;\n neg = true;\n }\n while (n > 0) {\n bts[i++] = _utoa(uint8(uint256(n) % radix)); // Turn it to ascii.\n n = int256(uint256(n) / radix);\n }\n // Reverse\n uint256 size = i;\n uint256 j = 0;\n bytes memory rev;\n if (neg) {\n size++;\n j = 1;\n rev = new bytes(size);\n rev[0] = MINUS;\n } else rev = new bytes(size);\n\n for (; j < size; j++) rev[j] = bts[size - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint)\n\n Convert an unsigned integer to a string.\n\n Params:\n n (uint) - The unsigned integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n\n Returns:\n result (string) - The resulting string.\n */\n function _utoa(uint256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n while (n > 0) {\n bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.\n n /= radix;\n }\n // Reverse\n bytes memory rev = new bytes(i);\n for (uint256 j = 0; j < i; j++) rev[j] = bts[i - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(int)\n\n Add a tag to an int.\n\n Params:\n value (int) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _itoa(value)\"\n */\n function _tag(int256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _itoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _tag(uint)\n\n Add a tag to an uint.\n\n Params:\n value (uint) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _utoa(value)\"\n */\n function _tag(uint256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _utoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertAddressArray.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertAddressArray {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** address[] **************************************\n\n /*\n Function: equal(address[])\n\n Assert that two 'address[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (address[]) - The first array.\n B (address[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n address[] memory arrA,\n address[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n _report(result, message);\n }\n\n /*\n Function: notEqual(address[])\n\n Assert that two 'address[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (address[]) - The first string.\n B (address[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n address[] memory arrA,\n address[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n result = !result;\n _report(result, message);\n }\n\n /*\n Function: lengthEqual(address[])\n\n Assert that the length of an 'address[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (address[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n address[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength == length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /*\n Function: lengthNotEqual(address[])\n\n Assert that the length of an 'address[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (address[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n address[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength != arr.length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _utoa(uint)\n\n Convert an unsigned integer to a string.\n\n Params:\n n (uint) - The unsigned integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n\n Returns:\n result (string) - The resulting string.\n */\n function _utoa(uint256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n while (n > 0) {\n bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.\n n /= radix;\n }\n // Reverse\n bytes memory rev = new bytes(i);\n for (uint256 j = 0; j < i; j++) rev[j] = bts[i - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(uint)\n\n Add a tag to an uint.\n\n Params:\n value (uint) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _utoa(value)\"\n */\n function _tag(uint256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _utoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertBytes32Array.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertBytes32Array {\n uint8 constant ZERO = uint8(bytes1(\"0\"));\n uint8 constant A = uint8(bytes1(\"a\"));\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** bytes32[] **************************************\n\n /*\n Function: equal(bytes32[])\n\n Assert that two 'bytes32[]' are equal.\n\n : arrA.length == arrB.length\n\n and, for all valid indices 'i'\n\n : arrA[i] == arrB[i]\n\n Params:\n A (bytes32[]) - The first array.\n B (bytes32[]) - The second array.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function equal(\n bytes32[] memory arrA,\n bytes32[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n _report(result, message);\n }\n\n /*\n Function: notEqual(bytes32[])\n\n Assert that two 'bytes32[]' are not equal.\n\n : arrA.length != arrB.length\n\n or, for some valid index 'i'\n\n : arrA[i] != arrB[i]\n\n Params:\n A (bytes32[]) - The first string.\n B (bytes32[]) - The second string.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function notEqual(\n bytes32[] memory arrA,\n bytes32[] memory arrB,\n string memory message\n ) public returns (bool result) {\n result = arrA.length == arrB.length;\n if (result) {\n for (uint256 i = 0; i < arrA.length; i++) {\n if (arrA[i] != arrB[i]) {\n result = false;\n break;\n }\n }\n }\n result = !result;\n _report(result, message);\n }\n\n /*\n Function: lengthEqual(bytes32[])\n\n Assert that the length of an 'bytes32[]' is equal to a given value.\n\n : arr.length == length\n\n Params:\n arr (bytes32[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthEqual(\n bytes32[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength == length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /*\n Function: lengthNotEqual(bytes32[])\n\n Assert that the length of an 'bytes32[]' is not equal to a given value.\n\n : arr.length != length\n\n Params:\n arr (bytes32[]) - The array.\n length (uint) - The length.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function lengthNotEqual(\n bytes32[] memory arr,\n uint256 length,\n string memory message\n ) public returns (bool result) {\n uint256 arrLength = arr.length;\n if (arrLength != arr.length) _report(result, \"\");\n else _report(result, _appendTagged(_tag(arrLength, \"Tested\"), _tag(length, \"Against\"), message));\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n\n /*\n Function: _utoa(uint)\n\n Convert an unsigned integer to a string.\n\n Params:\n n (uint) - The unsigned integer.\n radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f\n\n Returns:\n result (string) - The resulting string.\n */\n function _utoa(uint256 n, uint8 radix) internal pure returns (string memory) {\n if (n == 0 || radix < 2 || radix > 16) return \"0\";\n bytes memory bts = new bytes(256);\n uint256 i;\n while (n > 0) {\n bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.\n n /= radix;\n }\n // Reverse\n bytes memory rev = new bytes(i);\n for (uint256 j = 0; j < i; j++) rev[j] = bts[i - j - 1];\n return string(rev);\n }\n\n /*\n Function: _utoa(uint8)\n\n Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',\n numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.\n\n Params:\n u (uint8) - The unsigned 8-bit integer.\n\n Returns:\n result (string) - The ASCII byte.\n */\n function _utoa(uint8 u) internal pure returns (bytes1) {\n if (u < 10) return bytes1(u + ZERO);\n else if (u < 16) return bytes1(u - 10 + A);\n else return 0;\n }\n\n /*\n function htoa(address addr) constant returns (string) {\n bytes memory bts = new bytes(40);\n bytes20 addrBts = bytes20(addr);\n for (uint i = 0; i < 20; i++) {\n bts[2*i] = addrBts[i] % 16;\n bts[2*i + 1] = (addrBts[i] / 16) % 16;\n }\n return string(bts);\n }\n\n */\n\n /*\n Function: _tag(string)\n\n Add a tag to a string. The 'value' and 'tag' strings are returned on the form \"tag: value\".\n\n Params:\n value (string) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: value\"\n */\n function _tag(string memory value, string memory tag) internal pure returns (string memory) {\n bytes memory valueB = bytes(value);\n bytes memory tagB = bytes(tag);\n\n uint256 vl = valueB.length;\n uint256 tl = tagB.length;\n\n bytes memory newB = new bytes(vl + tl + 2);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < tl; i++) newB[j++] = tagB[i];\n newB[j++] = \":\";\n newB[j++] = \" \";\n for (i = 0; i < vl; i++) newB[j++] = valueB[i];\n\n return string(newB);\n }\n\n /*\n Function: _tag(uint)\n\n Add a tag to an uint.\n\n Params:\n value (uint) - The value.\n tag (string) - The tag.\n\n Returns:\n result (string) - \"tag: _utoa(value)\"\n */\n function _tag(uint256 value, string memory tag) internal pure returns (string memory) {\n string memory nstr = _utoa(value, 10);\n return _tag(nstr, tag);\n }\n\n /*\n Function: _appendTagged(string, string)\n\n Append two tagged values to a string.\n\n Params:\n tagged0 (string) - The first tagged value.\n tagged1 (string) - The second tagged value.\n str (string) - The string.\n\n Returns:\n result (string) - \"str (tagged0, tagged1)\"\n */\n function _appendTagged(\n string memory tagged0,\n string memory tagged1,\n string memory str\n ) internal pure returns (string memory) {\n bytes memory tagged0B = bytes(tagged0);\n bytes memory tagged1B = bytes(tagged1);\n bytes memory strB = bytes(str);\n\n uint256 sl = strB.length;\n uint256 t0l = tagged0B.length;\n uint256 t1l = tagged1B.length;\n\n bytes memory newB = new bytes(sl + t0l + t1l + 5);\n\n uint256 i;\n uint256 j;\n\n for (i = 0; i < sl; i++) newB[j++] = strB[i];\n newB[j++] = \" \";\n newB[j++] = \"(\";\n for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i];\n newB[j++] = \",\";\n newB[j++] = \" \";\n for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i];\n newB[j++] = \")\";\n\n return string(newB);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertBalance.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertBalance {\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** balances **************************************\n\n /*\n Function: balanceEqual\n\n Assert that the balance of an account 'A' is equal to a given number 'b'.\n\n : A.balance = b\n\n Params:\n A (address) - The first address.\n b (uint) - The balance.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceEqual(\n address a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a.balance == b);\n _report(result, message);\n }\n\n /*\n Function: balanceNotEqual\n\n Assert that the balance of an account 'A' is not equal to a given number 'b'.\n\n : A.balance != b\n\n Params:\n A (address) - The first address.\n b (uint) - The balance.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceNotEqual(\n address a,\n uint256 b,\n string memory message\n ) public returns (bool result) {\n result = (a.balance != b);\n _report(result, message);\n }\n\n /*\n Function: balanceIsZero\n\n Assert that the balance of an account 'A' is zero.\n\n : A.balance == 0\n\n Params:\n A (address) - The first address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceIsZero(address a, string memory message) public returns (bool result) {\n result = (a.balance == 0);\n _report(result, message);\n }\n\n /*\n Function: balanceIsNotZero\n\n Assert that the balance of an account 'A' is not zero.\n\n : A.balance != 0\n\n Params:\n A (address) - The first address.\n message (string) - A message that is sent if the assertion fails.\n\n Returns:\n result (bool) - The result.\n */\n function balanceIsNotZero(address a, string memory message) public returns (bool result) {\n result = (a.balance != 0);\n _report(result, message);\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n}\n" + }, + "contracts/test/helpers/truffle/AssertGeneral.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nlibrary AssertGeneral {\n /*\n Event: TestEvent\n\n Fired when an assertion is made.\n\n Params:\n result (bool) - Whether or not the assertion holds.\n message (string) - A message to display if the assertion does not hold.\n */\n event TestEvent(bool indexed result, string message);\n\n // ************************************** general **************************************\n\n /*\n Function: fail()\n\n Mark the test as failed.\n\n Params:\n message (string) - A message associated with the failure.\n\n Returns:\n result (bool) - false.\n */\n function fail(string memory message) public returns (bool result) {\n _report(false, message);\n return false;\n }\n\n /******************************** internal ********************************/\n\n /*\n Function: _report\n\n Internal function for triggering .\n\n Params:\n result (bool) - The test result (true or false).\n message (string) - The message that is sent if the assertion fails.\n */\n function _report(bool result, string memory message) internal {\n if (result) emit TestEvent(true, \"\");\n else emit TestEvent(false, message);\n }\n}\n" + }, + "contracts/test/TestSortedDoublyLLUpdateKey.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/SortedDoublyLLFixture.sol\";\nimport \"./helpers/RevertProxy.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestSortedDoublyLLUpdateKey {\n address[] ids = [address(1), address(2), address(3), address(4), address(5), address(6)];\n uint256[] keys = [uint256(13), uint256(11), uint256(9), uint256(7), uint256(5), uint256(3)];\n\n SortedDoublyLLFixture fixture;\n RevertProxy proxy;\n\n function beforeAll() public {\n proxy = new RevertProxy();\n }\n\n function beforeEach() public {\n fixture = new SortedDoublyLLFixture();\n fixture.setMaxSize(10);\n }\n\n function test_updateKey_missingId() public {\n SortedDoublyLLFixture(address(proxy)).updateKey(ids[3], 5, address(0), address(0));\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n\n function test_updateKey_increaseNoHint() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n uint256 newKey = keys[3] + 3;\n fixture.updateKey(ids[3], newKey, address(0), address(0));\n Assert.equal(fixture.getKey(ids[3]), newKey, \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[2], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[1], \"wrong prev\");\n Assert.equal(fixture.getNext(ids[1]), ids[3], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[2]), ids[3], \"wrong prev\");\n }\n\n function test_updateKey_decreaseNoHint() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n uint256 newKey = keys[3] - 3;\n fixture.updateKey(ids[3], newKey, address(0), address(0));\n Assert.equal(fixture.getKey(ids[3]), newKey, \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[5], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[4], \"wrong prev\");\n Assert.equal(fixture.getNext(ids[4]), ids[3], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[5]), ids[3], \"wrong prev\");\n }\n\n function test_updateKey_zeroNewKey() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n\n uint256 newKey = 0;\n fixture.updateKey(ids[2], newKey, address(0), address(0));\n Assert.isFalse(fixture.contains(ids[2]), \"list should not contain id after updating with newKey = 0\");\n }\n}\n" + }, + "contracts/test/mocks/SortedDoublyLLFixture.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../libraries/SortedDoublyLL.sol\";\n\ncontract SortedDoublyLLFixture {\n using SortedDoublyLL for SortedDoublyLL.Data;\n\n SortedDoublyLL.Data list;\n\n function setMaxSize(uint256 _size) public {\n list.setMaxSize(_size);\n }\n\n function insert(\n address _id,\n uint256 _key,\n address _prevId,\n address _nextId\n ) public {\n list.insert(_id, _key, _prevId, _nextId);\n }\n\n function remove(address _id) public {\n list.remove(_id);\n }\n\n function updateKey(\n address _id,\n uint256 _newKey,\n address _prevId,\n address _nextId\n ) public {\n list.updateKey(_id, _newKey, _prevId, _nextId);\n }\n\n function contains(address _id) public view returns (bool) {\n return list.contains(_id);\n }\n\n function getSize() public view returns (uint256) {\n return list.getSize();\n }\n\n function getMaxSize() public view returns (uint256) {\n return list.maxSize;\n }\n\n function getKey(address _id) public view returns (uint256) {\n return list.getKey(_id);\n }\n\n function getFirst() public view returns (address) {\n return list.getFirst();\n }\n\n function getLast() public view returns (address) {\n return list.getLast();\n }\n\n function getNext(address _id) public view returns (address) {\n return list.getNext(_id);\n }\n\n function getPrev(address _id) public view returns (address) {\n return list.getPrev(_id);\n }\n}\n" + }, + "contracts/test/helpers/RevertProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\ncontract RevertProxy {\n bytes data;\n\n fallback() external {\n data = msg.data;\n }\n\n // solium-disable security/no-low-level-calls\n function execute(address _target) external returns (bool) {\n (bool ok, ) = _target.call(data);\n return ok;\n }\n}\n" + }, + "contracts/test/TestSortedDoublyLLRemove.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/SortedDoublyLLFixture.sol\";\nimport \"./helpers/RevertProxy.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestSortedDoublyLLRemove {\n address[] ids = [address(1), address(2), address(3), address(4), address(5), address(6)];\n uint256[] keys = [uint256(13), uint256(11), uint256(9), uint256(7), uint256(5), uint256(3)];\n\n SortedDoublyLLFixture fixture;\n RevertProxy proxy;\n\n function beforeAll() public {\n proxy = new RevertProxy();\n }\n\n function beforeEach() public {\n fixture = new SortedDoublyLLFixture();\n fixture.setMaxSize(10);\n }\n\n function test_remove() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n\n fixture.remove(ids[1]);\n Assert.equal(fixture.contains(ids[1]), false, \"should not contain node\");\n Assert.equal(fixture.getSize(), 2, \"wrong size\");\n Assert.equal(fixture.getNext(ids[0]), ids[2], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[2]), ids[0], \"wrong prev\");\n }\n\n function test_remove_singleNode() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n\n fixture.remove(ids[0]);\n Assert.equal(fixture.contains(ids[0]), false, \"should not contain node\");\n Assert.equal(fixture.getSize(), 0, \"wrong size\");\n Assert.equal(fixture.getFirst(), address(0), \"wrong head\");\n Assert.equal(fixture.getLast(), address(0), \"wrong tail\");\n }\n\n function test_remove_head() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n\n fixture.remove(ids[0]);\n Assert.equal(fixture.contains(ids[0]), false, \"should not contain node\");\n Assert.equal(fixture.getSize(), 1, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[1], \"wrong head\");\n Assert.equal(fixture.getPrev(ids[1]), address(0), \"wrong prev\");\n }\n\n function test_remove_tail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n\n fixture.remove(ids[1]);\n Assert.equal(fixture.contains(ids[1]), false, \"should not contain node\");\n Assert.equal(fixture.getSize(), 1, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[0], \"wrong prev\");\n Assert.equal(fixture.getNext(ids[0]), address(0), \"wrong next\");\n }\n\n function test_remove_notInList() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n\n SortedDoublyLLFixture(address(proxy)).remove(ids[1]);\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n}\n" + }, + "contracts/test/TestSortedDoublyLLInsert.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/SortedDoublyLLFixture.sol\";\nimport \"./helpers/RevertProxy.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestSortedDoublyLLInsert {\n address[] ids = [address(1), address(2), address(3), address(4), address(5), address(6)];\n uint256[] keys = [uint256(13), uint256(11), uint256(9), uint256(7), uint256(5), uint256(5), uint256(3)];\n\n SortedDoublyLLFixture fixture;\n RevertProxy proxy;\n\n function beforeAll() public {\n proxy = new RevertProxy();\n }\n\n function beforeEach() public {\n fixture = new SortedDoublyLLFixture();\n fixture.setMaxSize(3);\n }\n\n function test_setMaxSize() public {\n Assert.equal(fixture.getMaxSize(), 3, \"wrong max size\");\n }\n\n function test_setMaxSize_update() public {\n fixture.setMaxSize(10);\n\n Assert.equal(fixture.getMaxSize(), 10, \"wrong max size\");\n }\n\n function test_setMaxSize_decreaseSize() public {\n SortedDoublyLLFixture(address(proxy)).setMaxSize(1);\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n\n function test_insert_empty() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n Assert.equal(fixture.getSize(), 1, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[0], \"wrong head\");\n Assert.equal(fixture.getLast(), ids[0], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[0]), keys[0], \"wrong key\");\n Assert.equal(fixture.getNext(ids[0]), address(0), \"wrong next\");\n Assert.equal(fixture.getPrev(ids[0]), address(0), \"wrong prev\");\n }\n\n function test_insert_updateHead() public {\n fixture.insert(ids[1], keys[1], address(0), address(0));\n\n fixture.insert(ids[0], keys[0], address(0), ids[1]);\n Assert.equal(fixture.getSize(), 2, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[0], \"wrong head\");\n Assert.equal(fixture.getKey(ids[0]), keys[0], \"wrong key\");\n Assert.equal(fixture.getNext(ids[0]), ids[1], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[0]), address(0), \"wrong prev\");\n }\n\n function test_insert_updateTail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n Assert.equal(fixture.getSize(), 2, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[1], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[1]), keys[1], \"wrong key\");\n Assert.equal(fixture.getNext(ids[1]), address(0), \"wrong next\");\n Assert.equal(fixture.getPrev(ids[1]), ids[0], \"wrong prev\");\n }\n\n function test_insert_atPosition() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[2], keys[2], ids[0], address(0));\n\n fixture.insert(ids[1], keys[1], ids[0], ids[2]);\n Assert.equal(fixture.getSize(), 3, \"wrong size\");\n Assert.equal(fixture.getKey(ids[1]), keys[1], \"wrong stake\");\n Assert.equal(fixture.getNext(ids[1]), ids[2], \"wrong next transcoder\");\n Assert.equal(fixture.getPrev(ids[1]), ids[0], \"wrong prev transcoder\");\n }\n\n function test_insert_full() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n\n SortedDoublyLLFixture(address(proxy)).insert(ids[3], keys[3], address(0), address(0));\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n\n function test_insert_containsId() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n\n SortedDoublyLLFixture(address(proxy)).insert(ids[0], keys[0], address(0), address(0));\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n\n function test_insert_null() public {\n SortedDoublyLLFixture(address(proxy)).insert(address(0), keys[0], address(0), address(0));\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n\n function test_insert_zeroKey() public {\n SortedDoublyLLFixture(address(proxy)).insert(ids[0], 0, address(0), address(0));\n bool result = proxy.execute(address(fixture));\n Assert.isFalse(result, \"did not revert\");\n }\n}\n" + }, + "contracts/test/TestSortedDoublyLLFindWithHints2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/SortedDoublyLLFixture.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestSortedDoublyLLFindWithHints2 {\n address[] ids = [address(1), address(2), address(3), address(4), address(5), address(6)];\n uint256[] keys = [uint256(13), uint256(11), uint256(9), uint256(7), uint256(5), uint256(3)];\n\n SortedDoublyLLFixture fixture;\n\n function beforeEach() public {\n fixture = new SortedDoublyLLFixture();\n fixture.setMaxSize(10);\n }\n\n function test_insert_findWithHintPrevRemoved() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.remove(ids[2]);\n fixture.insert(ids[3], keys[3], ids[2], ids[4]);\n Assert.equal(fixture.getSize(), 5, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[4], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[1], \"wrong prev\");\n }\n\n function test_insert_findWithHintPrevRemovedUpdateHead() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.remove(ids[0]);\n fixture.insert(ids[1], keys[1], ids[0], ids[2]);\n Assert.equal(fixture.getSize(), 5, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[1], \"wrong head\");\n Assert.equal(fixture.getKey(ids[1]), keys[1], \"wrong key\");\n Assert.equal(fixture.getNext(ids[1]), ids[2], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[1]), address(0), \"wrong prev\");\n }\n\n function test_insert_findWithHintPrevDecreased() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.updateKey(ids[2], 6, address(0), address(0));\n fixture.insert(ids[3], keys[3], ids[2], ids[4]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[2], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[1], \"wrong prev\");\n }\n\n function test_insert_findWithHintNextRemoved() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.remove(ids[4]);\n fixture.insert(ids[3], keys[3], ids[2], ids[4]);\n Assert.equal(fixture.getSize(), 5, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[5], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[2], \"wrong prev\");\n }\n\n function test_insert_findWithHintNextRemovedUpdateTail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[3], address(0));\n\n fixture.remove(ids[5]);\n fixture.insert(ids[4], keys[4], ids[3], ids[5]);\n Assert.equal(fixture.getSize(), 5, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[4], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[4]), keys[4], \"wrong key\");\n Assert.equal(fixture.getNext(ids[4]), address(0), \"wrong next\");\n Assert.equal(fixture.getPrev(ids[4]), ids[3], \"wrong prev\");\n }\n\n function test_insert_findWithHintNextIncreased() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.updateKey(ids[4], 8, address(0), address(0));\n fixture.insert(ids[3], keys[3], ids[2], ids[4]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[5], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[4], \"wrong prev\");\n }\n\n function test_insert_findWithHintNotTightBound() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[3], keys[3], ids[0], ids[5]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[4], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[2], \"wrong prev\");\n }\n}\n" + }, + "contracts/test/TestSortedDoublyLLFindWithHints.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/SortedDoublyLLFixture.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestSortedDoublyLLFindWithHints {\n address[] ids = [address(1), address(2), address(3), address(4), address(5), address(6)];\n uint256[] keys = [uint256(13), uint256(11), uint256(9), uint256(7), uint256(5), uint256(3)];\n\n SortedDoublyLLFixture fixture;\n\n function beforeEach() public {\n fixture = new SortedDoublyLLFixture();\n fixture.setMaxSize(10);\n }\n\n function test_insert_findNoHintUpdateHead() public {\n fixture.insert(ids[1], keys[1], address(0), address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[0], keys[0], address(0), address(0));\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[0], \"wrong head\");\n Assert.equal(fixture.getKey(ids[0]), keys[0], \"wrong key\");\n Assert.equal(fixture.getNext(ids[0]), ids[1], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[0]), address(0), \"wrong prev\");\n }\n\n function test_insert_findNoHintUpdateTail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n\n fixture.insert(ids[5], keys[5], address(0), address(0));\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[5], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[5]), keys[5], \"wrong key\");\n Assert.equal(fixture.getNext(ids[5]), address(0), \"wrong next transcoder\");\n Assert.equal(fixture.getPrev(ids[5]), ids[4], \"wrong prev transcoder\");\n }\n\n function test_insert_findNoHintAtPosition() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[3], keys[3], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[2], keys[2], address(0), address(0));\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[2]), keys[2], \"wrong\");\n Assert.equal(fixture.getNext(ids[2]), ids[3], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[2]), ids[1], \"wrong prev\");\n }\n\n function test_insert_findWithHintNextUpdateHead() public {\n fixture.insert(ids[1], keys[1], address(0), address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[0], keys[0], address(0), ids[2]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getFirst(), ids[0], \"wrong head\");\n Assert.equal(fixture.getKey(ids[0]), keys[0], \"wrong key\");\n Assert.equal(fixture.getNext(ids[0]), ids[1], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[0]), address(0), \"wrong prev\");\n }\n\n function test_insert_findWithHintNextUpdateTail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[2], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[1], 3, address(0), ids[5]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[1], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[1]), 3, \"wrong key\");\n Assert.equal(fixture.getNext(ids[1]), address(0), \"wrong next\");\n Assert.equal(fixture.getPrev(ids[1]), ids[5], \"wrong prev\");\n }\n\n function test_insert_findWithHintNextAtPosition() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[3], keys[3], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[2], keys[2], address(0), ids[3]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[2]), keys[2], \"wrong key\");\n Assert.equal(fixture.getNext(ids[2]), ids[3], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[2]), ids[1], \"wrong prev\");\n }\n\n function test_insert_findWithHintPrevUpdateTail() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[3], keys[3], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n\n fixture.insert(ids[5], keys[5], ids[1], address(0));\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getLast(), ids[5], \"wrong tail\");\n Assert.equal(fixture.getKey(ids[5]), keys[5], \"wrong key\");\n Assert.equal(fixture.getNext(ids[5]), address(0), \"wrong next\");\n Assert.equal(fixture.getPrev(ids[5]), ids[4], \"wrong prev\");\n }\n\n function test_insert_findWithHintPrevAtPosition() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[3], keys[3], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[3], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[2], keys[2], ids[0], address(0));\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[2]), keys[2], \"wrong key\");\n Assert.equal(fixture.getNext(ids[2]), ids[3], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[2]), ids[1], \"wrong prev\");\n }\n\n function test_insert_findWithHint() public {\n fixture.insert(ids[0], keys[0], address(0), address(0));\n fixture.insert(ids[1], keys[1], ids[0], address(0));\n fixture.insert(ids[2], keys[2], ids[1], address(0));\n fixture.insert(ids[4], keys[4], ids[2], address(0));\n fixture.insert(ids[5], keys[5], ids[4], address(0));\n\n fixture.insert(ids[3], keys[3], ids[2], ids[4]);\n Assert.equal(fixture.getSize(), 6, \"wrong size\");\n Assert.equal(fixture.getKey(ids[3]), keys[3], \"wrong key\");\n Assert.equal(fixture.getNext(ids[3]), ids[4], \"wrong next\");\n Assert.equal(fixture.getPrev(ids[3]), ids[2], \"wrong prev\");\n }\n}\n" + }, + "contracts/test/TestSortedArrays.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./helpers/truffle/Assert.sol\";\nimport \"./helpers/RevertProxy.sol\";\nimport \"./mocks/SortedArraysFixture.sol\";\n\ncontract TestSortedArrays {\n RevertProxy proxy;\n SortedArraysFixture fixture;\n\n function beforeAll() public {\n proxy = new RevertProxy();\n }\n\n function beforeEach() public {\n fixture = new SortedArraysFixture();\n }\n\n function test_pushSorted_addsElements() public {\n fixture.pushSorted(3);\n Assert.equal(fixture.length(), 1, \"incorrect array length\");\n Assert.equal(fixture.array(0), 3, \"incorrect value in array\");\n\n fixture.pushSorted(4);\n Assert.equal(fixture.length(), 2, \"incorrect array length\");\n Assert.equal(fixture.array(0), 3, \"incorrect value in array\");\n Assert.equal(fixture.array(1), 4, \"incorrect value in array\");\n }\n\n function test_pushSorted_avoidsDuplicates() public {\n fixture.pushSorted(4);\n Assert.equal(fixture.length(), 1, \"incorrect array length\");\n Assert.equal(fixture.array(0), 4, \"incorrect value in array\");\n\n fixture.pushSorted(4);\n Assert.equal(fixture.length(), 1, \"incorrect array length\");\n }\n\n function test_pushSorted_revertsOnDecreasing() public {\n fixture.pushSorted(4);\n Assert.equal(fixture.length(), 1, \"incorrect array length\");\n Assert.equal(fixture.array(0), 4, \"incorrect value in array\");\n\n SortedArraysFixture(address(proxy)).pushSorted(3);\n bool ok = proxy.execute(address(fixture));\n Assert.isFalse(ok, \"did not revert\");\n }\n\n function test_findLowerBound_lowerThanElement() public {\n fixture.pushSorted(2);\n fixture.pushSorted(4);\n fixture.pushSorted(7);\n fixture.pushSorted(11);\n\n Assert.equal(fixture.findLowerBound(3), 0, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(6), 1, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(10), 2, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(15), 3, \"found incorrect element\");\n }\n\n function test_findLowerBound_exactElement() public {\n fixture.pushSorted(3);\n fixture.pushSorted(5);\n fixture.pushSorted(8);\n fixture.pushSorted(13);\n\n Assert.equal(fixture.findLowerBound(3), 0, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(5), 1, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(8), 2, \"found incorrect element\");\n Assert.equal(fixture.findLowerBound(13), 3, \"found incorrect element\");\n }\n\n function test_findLowerBound_returnsLengthOnEmpty() public {\n Assert.equal(fixture.length(), 0, \"incorrect array length\");\n Assert.equal(fixture.findLowerBound(3), 0, \"incorrect return on empty array\");\n }\n\n function test_findLowerBound_returnsLengthOnNotFound() public {\n fixture.pushSorted(8);\n fixture.pushSorted(13);\n\n Assert.equal(fixture.findLowerBound(22), 1, \"found incorrect element\");\n // looking for a value lower than min should return the array length\n Assert.equal(fixture.findLowerBound(5), 2, \"incorrect return on not found\");\n }\n}\n" + }, + "contracts/test/mocks/SortedArraysFixture.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../bonding/libraries/SortedArrays.sol\";\n\ncontract SortedArraysFixture {\n uint256[] public array;\n\n function findLowerBound(uint256 val) external view returns (uint256) {\n return SortedArrays.findLowerBound(array, val);\n }\n\n function pushSorted(uint256 val) external {\n SortedArrays.pushSorted(array, val);\n }\n\n function length() external view returns (uint256) {\n return array.length;\n }\n}\n" + }, + "contracts/bonding/libraries/SortedArrays.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../libraries/MathUtils.sol\";\n\nimport \"@openzeppelin/contracts/utils/Arrays.sol\";\n\n/**\n * @title SortedArrays\n * @dev Handles maintaining and looking up on sorted uint256 arrays.\n */\nlibrary SortedArrays {\n using Arrays for uint256[];\n\n error DecreasingValues(uint256 newValue, uint256 lastValue);\n\n /**\n * @notice Searches a sorted _array and returns the last element to be lower or equal to _val. If there is no such\n * element (all elements in array are higher than the searched element), the array length is returned.\n *\n * @dev This basically converts OpenZeppelin's {Arrays-findUpperBound} into findLowerBound, meaning it also uses a\n * binary search in the worst case after trying some shortcuts. Worst case time complexity is O(log n). The only\n * change being that the returned index points to the element lower or equal to _val, instead of higher or equal.\n * @param _array Array to search in\n * @param _val Value to search for\n * @return lower Index of the lower bound found in array\n */\n function findLowerBound(uint256[] storage _array, uint256 _val) internal view returns (uint256) {\n uint256 len = _array.length;\n if (len == 0) {\n return 0;\n }\n\n if (_array[len - 1] <= _val) {\n return len - 1;\n }\n\n uint256 upperIdx = _array.findUpperBound(_val);\n\n // we already checked the last element above so the upper will always be inside the array\n assert(upperIdx < len);\n\n // the exact value we were searching is in the array\n if (_array[upperIdx] == _val) {\n return upperIdx;\n }\n\n // a 0 idx means that the first elem is already higher than the searched value (and not equal, checked above)\n if (upperIdx == 0) {\n return len;\n }\n\n // the element at upperIdx is the first element higher than the value we want, so return the previous element\n return upperIdx - 1;\n }\n\n /**\n * @notice Pushes a value into an already sorted array.\n * @dev Values must be pushed in increasing order as to avoid shifting values in the array. This function only\n * guarantees that the pushed value will not create duplicates nor make the array out of order.\n * @param array Array to push the value into\n * @param val Value to push into array. Must be greater than or equal to the highest (last) element.\n */\n function pushSorted(uint256[] storage array, uint256 val) internal {\n if (array.length == 0) {\n array.push(val);\n } else {\n uint256 last = array[array.length - 1];\n\n // values must be pushed in order\n if (val < last) {\n revert DecreasingValues(val, last);\n }\n\n // don't push duplicate values\n if (val != last) {\n array.push(val);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Arrays.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./StorageSlot.sol\";\nimport \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n using StorageSlot for bytes32;\n\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = Math.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (unsafeAccess(array, mid).value > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getAddressSlot();\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getBytes32Slot();\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getUint256Slot();\n }\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "contracts/test/mocks/VotesMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport { IVotes } from \"../../treasury/GovernorCountingOverridable.sol\";\nimport \"../../bonding/libraries/SortedArrays.sol\";\n\n/**\n * @dev Minimum implementation of an IVotes interface to test the GovernorCountingOverridable extension. It inherits\n * from the default ERC20VotesUpgradeable implementation but overrides the voting power functions to provide power to\n * delegators as well (to be made overridable by the GovernorCountingOverridable extension).\n */\ncontract VotesMock is\n Initializable,\n ERC20Upgradeable,\n ERC20BurnableUpgradeable,\n OwnableUpgradeable,\n ERC20VotesUpgradeable,\n IVotes\n{\n function initialize() public initializer {\n __ERC20_init(\"VotesMock\", \"VTCK\");\n __ERC20Burnable_init();\n __Ownable_init();\n __ERC20Votes_init();\n }\n\n function delegatedAt(address _account, uint256 _timepoint) external view returns (address) {\n _timepoint; // unused\n // Blatant simplification that only works in our tests where we never change participants balance during\n // proposal voting period. We check and return delegators current state instead of tracking historical values.\n return delegates(_account);\n }\n\n /**\n * @dev Simulates the behavior of our actual voting power, where the delegator also has voting power which can\n * override their transcoder's vote. This is not the case in the OpenZeppelin implementation.\n */\n function getPastVotes(address account, uint256 blockNumber)\n public\n view\n override(IVotesUpgradeable, ERC20VotesUpgradeable)\n returns (uint256)\n {\n // Blatant simplification that only works in our tests where we never change participants balance during\n // proposal voting period. We check and return delegators current state instead of tracking historical values.\n if (delegates(account) != account) {\n return balanceOf(account);\n }\n return super.getPastVotes(account, blockNumber);\n }\n\n /**\n * @dev Same as above. Still don't understand why the OZ implementation for these 2 is incompatible, with getPast*\n * reverting if you query it with the current round.\n */\n function getVotes(address account)\n public\n view\n override(IVotesUpgradeable, ERC20VotesUpgradeable)\n returns (uint256)\n {\n if (delegates(account) != account) {\n return balanceOf(account);\n }\n return super.getVotes(account);\n }\n\n function mint(address to, uint256 amount) public onlyOwner {\n _mint(to, amount);\n }\n\n // The following functions are overrides required by Solidity.\n\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {\n super._afterTokenTransfer(from, to, amount);\n }\n\n function _mint(address to, uint256 amount) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {\n super._mint(to, amount);\n }\n\n function _burn(address account, uint256 amount) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {\n super._burn(account, amount);\n }\n\n function name() public view override(IVotes, ERC20Upgradeable) returns (string memory) {\n return super.name();\n }\n\n function symbol() public view override(IVotes, ERC20Upgradeable) returns (string memory) {\n return super.symbol();\n }\n\n function decimals() public view override(IVotes, ERC20Upgradeable) returns (uint8) {\n return super.decimals();\n }\n\n function totalSupply() public view override(IVotes, ERC20Upgradeable) returns (uint256) {\n return super.totalSupply();\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {\n function __ERC20Burnable_init() internal onlyInitializing {\n }\n\n function __ERC20Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC20PermitUpgradeable.sol\";\nimport \"../../../interfaces/IERC5805Upgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, ERC20PermitUpgradeable, IERC5805Upgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\n */\n function clock() public view virtual override returns (uint48) {\n return SafeCastUpgradeable.toUint48(block.number);\n }\n\n /**\n * @dev Description of the clock\n */\n // solhint-disable-next-line func-name-mixedcase\n function CLOCK_MODE() public view virtual override returns (string memory) {\n // Check that the clock was not modified\n require(clock() == block.number, \"ERC20Votes: broken clock mode\");\n return \"mode=blocknumber&from=default\";\n }\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n unchecked {\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `timepoint`.\n *\n * Requirements:\n *\n * - `timepoint` must be in the past\n */\n function getPastVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {\n require(timepoint < clock(), \"ERC20Votes: future lookup\");\n return _checkpointsLookup(_checkpoints[account], timepoint);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `timepoint`. Note, this value is the sum of all balances.\n * It is NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `timepoint` must be in the past\n */\n function getPastTotalSupply(uint256 timepoint) public view virtual override returns (uint256) {\n require(timepoint < clock(), \"ERC20Votes: future lookup\");\n return _checkpointsLookup(_totalSupplyCheckpoints, timepoint);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 timepoint) private view returns (uint256) {\n // We run a binary search to look for the last (most recent) checkpoint taken before (or at) `timepoint`.\n //\n // Initially we check if the block is recent to narrow the search range.\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `timepoint`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `timepoint`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `timepoint`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `timepoint`, but it works out\n // the same.\n uint256 length = ckpts.length;\n\n uint256 low = 0;\n uint256 high = length;\n\n if (length > 5) {\n uint256 mid = length - MathUpgradeable.sqrt(length);\n if (_unsafeAccess(ckpts, mid).fromBlock > timepoint) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(ckpts, mid).fromBlock > timepoint) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n unchecked {\n return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes;\n }\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {IVotes-DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(address src, address dst, uint256 amount) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n\n unchecked {\n Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1);\n\n oldWeight = oldCkpt.votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && oldCkpt.fromBlock == clock()) {\n _unsafeAccess(ckpts, pos - 1).votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(clock()), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n */\n function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) {\n assembly {\n mstore(0, ckpts.slot)\n result.slot := add(keccak256(0, 0x20), pos)\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "contracts/treasury/GovernorCountingOverridable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC5805Upgradeable.sol\";\n\nimport \"../bonding/libraries/EarningsPool.sol\";\nimport \"../bonding/libraries/EarningsPoolLIP36.sol\";\n\nimport \"../Manager.sol\";\nimport \"../IController.sol\";\nimport \"../rounds/IRoundsManager.sol\";\nimport \"./IVotes.sol\";\n\n/**\n * @title GovernorCountingOverridable\n * @notice Implements the Counting module from OpenZeppelin Governor with support for delegators overriding their\n * delegated transcoder's vote. This module is used through inheritance by the Governor contract, which must implement\n * the `votes()` function to provide an instance of the IVotes interface.\n */\nabstract contract GovernorCountingOverridable is Initializable, GovernorUpgradeable {\n error InvalidVoteType(uint8 voteType);\n error VoteAlreadyCast();\n\n /**\n * @dev Supported vote types. Matches Governor Bravo ordering.\n */\n enum VoteType {\n Against,\n For,\n Abstain\n }\n\n /**\n * @dev Tracks state of specicic voters in a single proposal.\n */\n struct ProposalVoterState {\n bool hasVoted;\n VoteType support;\n // This vote deductions state is only necessary to support the case where a delegator might vote before their\n // transcoder. When that happens, we need to deduct the delegator(s) votes before tallying the transcoder vote.\n uint256 deductions;\n }\n\n /**\n * @dev Tracks the tallying state for a proposal vote counting logic.\n */\n struct ProposalTally {\n uint256 againstVotes;\n uint256 forVotes;\n uint256 abstainVotes;\n mapping(address => ProposalVoterState) voters;\n }\n\n // Maps proposal IDs to their corresponding vote tallies.\n mapping(uint256 => ProposalTally) private _proposalTallies;\n\n /**\n * @notice The required percentage of \"for\" votes in relation to the total opinionated votes (for and against) for\n * a proposal to succeed. Represented as a MathUtils percentage value (e.g. 6 decimal places).\n */\n uint256 public quota;\n\n function __GovernorCountingOverridable_init(uint256 _quota) internal onlyInitializing {\n __GovernorCountingOverridable_init_unchained(_quota);\n }\n\n function __GovernorCountingOverridable_init_unchained(uint256 _quota) internal onlyInitializing {\n quota = _quota;\n }\n\n /**\n * @dev See {IGovernor-COUNTING_MODE}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function COUNTING_MODE() public pure virtual override returns (string memory) {\n return \"support=bravo&quorum=for,abstain,against\";\n }\n\n /**\n * @dev See {IGovernor-hasVoted}.\n */\n function hasVoted(uint256 _proposalId, address _account) public view virtual override returns (bool) {\n return _proposalTallies[_proposalId].voters[_account].hasVoted;\n }\n\n /**\n * @dev Accessor to the internal vote counts.\n */\n function proposalVotes(uint256 _proposalId)\n public\n view\n virtual\n returns (\n uint256 againstVotes,\n uint256 forVotes,\n uint256 abstainVotes\n )\n {\n ProposalTally storage tally = _proposalTallies[_proposalId];\n return (tally.againstVotes, tally.forVotes, tally.abstainVotes);\n }\n\n /**\n * @dev See {Governor-_quorumReached}.\n */\n function _quorumReached(uint256 _proposalId) internal view virtual override returns (bool) {\n (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = proposalVotes(_proposalId);\n\n uint256 totalVotes = againstVotes + forVotes + abstainVotes;\n\n return totalVotes >= quorum(proposalSnapshot(_proposalId));\n }\n\n /**\n * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be at least QUOTA of the total votes.\n */\n function _voteSucceeded(uint256 _proposalId) internal view virtual override returns (bool) {\n (uint256 againstVotes, uint256 forVotes, ) = proposalVotes(_proposalId);\n\n // We ignore abstain votes for vote succeeded calculation\n uint256 opinionatedVotes = againstVotes + forVotes;\n\n return forVotes >= MathUtils.percOf(opinionatedVotes, quota);\n }\n\n /**\n * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).\n */\n function _countVote(\n uint256 _proposalId,\n address _account,\n uint8 _supportInt,\n uint256 _weight,\n bytes memory // params\n ) internal virtual override {\n if (_supportInt > uint8(VoteType.Abstain)) {\n revert InvalidVoteType(_supportInt);\n }\n VoteType support = VoteType(_supportInt);\n\n ProposalTally storage tally = _proposalTallies[_proposalId];\n ProposalVoterState storage voter = tally.voters[_account];\n\n if (voter.hasVoted) {\n revert VoteAlreadyCast();\n }\n voter.hasVoted = true;\n voter.support = support;\n\n _weight = _handleVoteOverrides(_proposalId, tally, voter, _account, _weight);\n\n if (support == VoteType.Against) {\n tally.againstVotes += _weight;\n } else if (support == VoteType.For) {\n tally.forVotes += _weight;\n } else {\n tally.abstainVotes += _weight;\n }\n }\n\n /**\n * @notice Handles vote overrides that delegators can make to their\n * corresponding delegated transcoder votes. Usually only the transcoders\n * vote on proposals, but any delegator can change their part of the vote.\n * This tracks past votes and deduction on separate mappings in order to\n * calculate the effective voting power of each vote.\n * @param _proposalId ID of the proposal being voted on\n * @param _tally struct where the vote totals are tallied on\n * @param _voter struct where the specific voter state is tracked\n * @param _account current user making a vote\n * @param _weight voting weight of the user making the vote\n */\n function _handleVoteOverrides(\n uint256 _proposalId,\n ProposalTally storage _tally,\n ProposalVoterState storage _voter,\n address _account,\n uint256 _weight\n ) internal returns (uint256) {\n uint256 timepoint = proposalSnapshot(_proposalId);\n address delegate = votes().delegatedAt(_account, timepoint);\n\n // Notice that we don't need to check if the voting power is greater than zero to trigger the override logic\n // here, which would be the equivalent of the `bondedAmount > 0` check in {BondingVotes-isRegisteredTranscoder}.\n // This is because if the account has zero `bondedAmount`, then it and all its delegators will also have zero\n // voting power, meaning the `votes()` invariant still holds (`0 >= sum(N*0)`).\n bool isSelfDelegated = _account == delegate;\n if (isSelfDelegated) {\n // Deduce weight from any previous delegators for this self-delegating account to cast a vote.\n return _weight - _voter.deductions;\n }\n\n // Same as above, all we need to check here is for a self-delegation due to the `votes()` invariant.\n bool isDelegateSelfDelegated = delegate == votes().delegatedAt(delegate, timepoint);\n if (!isDelegateSelfDelegated) {\n // Do not override votes of non-self-delegating accounts since those don't get their voting power from the\n // sum of delegations to them, so the override logic doesn't apply.\n return _weight;\n }\n\n // This is a delegator, so add a deduction to the delegated transcoder\n ProposalVoterState storage delegateVoter = _tally.voters[delegate];\n delegateVoter.deductions += _weight;\n\n if (delegateVoter.hasVoted) {\n // This is a delegator overriding its delegated transcoder vote,\n // we need to update the current totals to move the weight of\n // the delegator vote to the right outcome.\n VoteType delegateSupport = delegateVoter.support;\n\n if (delegateSupport == VoteType.Against) {\n _tally.againstVotes -= _weight;\n } else if (delegateSupport == VoteType.For) {\n _tally.forVotes -= _weight;\n } else {\n assert(delegateSupport == VoteType.Abstain);\n _tally.abstainVotes -= _weight;\n }\n }\n\n return _weight;\n }\n\n /**\n * @notice Provides the IVotes contract for all voting power handling logics.\n * @dev The returned contract must guarantee this invariant at any given timepoint: if an `_account` delegates to\n * itself (self-delegation), then its voting power must be greater than or equal to the sum of the voting power of\n * all its delegators. In pseudo-code: `votes(_account) >= sum(votes(delegators(_account)))`\n */\n function votes() public view virtual returns (IVotes);\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./StorageSlotUpgradeable.sol\";\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n using StorageSlotUpgradeable for bytes32;\n\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (unsafeAccess(array, mid).value > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.AddressSlot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getAddressSlot();\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.Bytes32Slot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getBytes32Slot();\n }\n\n /**\n * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n *\n * WARNING: Only use if you are certain `pos` is lower than the array length.\n */\n function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlotUpgradeable.Uint256Slot storage) {\n bytes32 slot;\n // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr`\n // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays.\n\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0, arr.slot)\n slot := add(keccak256(0, 0x20), pos)\n }\n return slot.getUint256Slot();\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/cryptography/EIP712Upgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = MathUpgradeable.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, MathUpgradeable.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.1) (governance/Governor.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"../token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../utils/cryptography/EIP712Upgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../utils/math/SafeCastUpgradeable.sol\";\nimport \"../utils/structs/DoubleEndedQueueUpgradeable.sol\";\nimport \"../utils/AddressUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"./IGovernorUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Core of the governance system, designed to be extended though various modules.\n *\n * This contract is abstract and requires several functions to be implemented in various modules:\n *\n * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}\n * - A voting module must implement {_getVotes}\n * - Additionally, {votingPeriod} must also be implemented\n *\n * _Available since v4.3._\n */\nabstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, EIP712Upgradeable, IGovernorUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable {\n using DoubleEndedQueueUpgradeable for DoubleEndedQueueUpgradeable.Bytes32Deque;\n\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n bytes32 public constant EXTENDED_BALLOT_TYPEHASH =\n keccak256(\"ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)\");\n\n // solhint-disable var-name-mixedcase\n struct ProposalCore {\n // --- start retyped from Timers.BlockNumber at offset 0x00 ---\n uint64 voteStart;\n address proposer;\n bytes4 __gap_unused0;\n // --- start retyped from Timers.BlockNumber at offset 0x20 ---\n uint64 voteEnd;\n bytes24 __gap_unused1;\n // --- Remaining fields starting at offset 0x40 ---------------\n bool executed;\n bool canceled;\n }\n // solhint-enable var-name-mixedcase\n\n string private _name;\n\n /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore)\n mapping(uint256 => ProposalCore) private _proposals;\n\n // This queue keeps track of the governor operating on itself. Calls to functions protected by the\n // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute},\n // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the\n // execution of {onlyGovernance} protected calls can only be achieved through successful proposals.\n DoubleEndedQueueUpgradeable.Bytes32Deque private _governanceCall;\n\n /**\n * @dev Restricts a function so it can only be executed through governance proposals. For example, governance\n * parameter setters in {GovernorSettings} are protected using this modifier.\n *\n * The governance executing address may be different from the Governor's own address, for example it could be a\n * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these\n * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus,\n * for example, additional timelock proposers are not able to change governance parameters without going through the\n * governance protocol (since v4.6).\n */\n modifier onlyGovernance() {\n require(_msgSender() == _executor(), \"Governor: onlyGovernance\");\n if (_executor() != address(this)) {\n bytes32 msgDataHash = keccak256(_msgData());\n // loop until popping the expected operation - throw if deque is empty (operation not authorized)\n while (_governanceCall.popFront() != msgDataHash) {}\n }\n _;\n }\n\n /**\n * @dev Sets the value for {name} and {version}\n */\n function __Governor_init(string memory name_) internal onlyInitializing {\n __EIP712_init_unchained(name_, version());\n __Governor_init_unchained(name_);\n }\n\n function __Governor_init_unchained(string memory name_) internal onlyInitializing {\n _name = name_;\n }\n\n /**\n * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract)\n */\n receive() external payable virtual {\n require(_executor() == address(this), \"Governor: must send to executor\");\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector;\n\n bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^\n this.castVoteWithReasonAndParamsBySig.selector ^\n this.getVotesWithParams.selector;\n\n // The original interface id in v4.3.\n bytes4 governor43Id = type(IGovernorUpgradeable).interfaceId ^\n type(IERC6372Upgradeable).interfaceId ^\n governorCancelId ^\n governorParamsId;\n\n // An updated interface id in v4.6, with params added.\n bytes4 governor46Id = type(IGovernorUpgradeable).interfaceId ^ type(IERC6372Upgradeable).interfaceId ^ governorCancelId;\n\n // For the updated interface id in v4.9, we use governorCancelId directly.\n\n return\n interfaceId == governor43Id ||\n interfaceId == governor46Id ||\n interfaceId == governorCancelId ||\n interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IGovernor-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IGovernor-version}.\n */\n function version() public view virtual override returns (string memory) {\n return \"1\";\n }\n\n /**\n * @dev See {IGovernor-hashProposal}.\n *\n * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array\n * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id\n * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in\n * advance, before the proposal is submitted.\n *\n * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the\n * same proposal (with same operation and same description) will have the same id if submitted on multiple governors\n * across multiple networks. This also means that in order to execute the same operation twice (on the same\n * governor) the proposer will have to change the description in order to avoid proposal id conflicts.\n */\n function hashProposal(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash)));\n }\n\n /**\n * @dev See {IGovernor-state}.\n */\n function state(uint256 proposalId) public view virtual override returns (ProposalState) {\n ProposalCore storage proposal = _proposals[proposalId];\n\n if (proposal.executed) {\n return ProposalState.Executed;\n }\n\n if (proposal.canceled) {\n return ProposalState.Canceled;\n }\n\n uint256 snapshot = proposalSnapshot(proposalId);\n\n if (snapshot == 0) {\n revert(\"Governor: unknown proposal id\");\n }\n\n uint256 currentTimepoint = clock();\n\n if (snapshot >= currentTimepoint) {\n return ProposalState.Pending;\n }\n\n uint256 deadline = proposalDeadline(proposalId);\n\n if (deadline >= currentTimepoint) {\n return ProposalState.Active;\n }\n\n if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) {\n return ProposalState.Succeeded;\n } else {\n return ProposalState.Defeated;\n }\n }\n\n /**\n * @dev Part of the Governor Bravo's interface: _\"The number of votes required in order for a voter to become a proposer\"_.\n */\n function proposalThreshold() public view virtual returns (uint256) {\n return 0;\n }\n\n /**\n * @dev See {IGovernor-proposalSnapshot}.\n */\n function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) {\n return _proposals[proposalId].voteStart;\n }\n\n /**\n * @dev See {IGovernor-proposalDeadline}.\n */\n function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {\n return _proposals[proposalId].voteEnd;\n }\n\n /**\n * @dev Returns the account that created a given proposal.\n */\n function proposalProposer(uint256 proposalId) public view virtual override returns (address) {\n return _proposals[proposalId].proposer;\n }\n\n /**\n * @dev Amount of votes already cast passes the threshold limit.\n */\n function _quorumReached(uint256 proposalId) internal view virtual returns (bool);\n\n /**\n * @dev Is the proposal successful or not.\n */\n function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);\n\n /**\n * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`.\n */\n function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256);\n\n /**\n * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`.\n *\n * Note: Support is generic and can represent various things depending on the voting system used.\n */\n function _countVote(\n uint256 proposalId,\n address account,\n uint8 support,\n uint256 weight,\n bytes memory params\n ) internal virtual;\n\n /**\n * @dev Default additional encoded parameters used by castVote methods that don't include them\n *\n * Note: Should be overridden by specific implementations to use an appropriate value, the\n * meaning of the additional params, in the context of that implementation\n */\n function _defaultParams() internal view virtual returns (bytes memory) {\n return \"\";\n }\n\n /**\n * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}.\n */\n function propose(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n string memory description\n ) public virtual override returns (uint256) {\n address proposer = _msgSender();\n require(_isValidDescriptionForProposer(proposer, description), \"Governor: proposer restricted\");\n\n uint256 currentTimepoint = clock();\n require(\n getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(),\n \"Governor: proposer votes below proposal threshold\"\n );\n\n uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description)));\n\n require(targets.length == values.length, \"Governor: invalid proposal length\");\n require(targets.length == calldatas.length, \"Governor: invalid proposal length\");\n require(targets.length > 0, \"Governor: empty proposal\");\n require(_proposals[proposalId].voteStart == 0, \"Governor: proposal already exists\");\n\n uint256 snapshot = currentTimepoint + votingDelay();\n uint256 deadline = snapshot + votingPeriod();\n\n _proposals[proposalId] = ProposalCore({\n proposer: proposer,\n voteStart: SafeCastUpgradeable.toUint64(snapshot),\n voteEnd: SafeCastUpgradeable.toUint64(deadline),\n executed: false,\n canceled: false,\n __gap_unused0: 0,\n __gap_unused1: 0\n });\n\n emit ProposalCreated(\n proposalId,\n proposer,\n targets,\n values,\n new string[](targets.length),\n calldatas,\n snapshot,\n deadline,\n description\n );\n\n return proposalId;\n }\n\n /**\n * @dev See {IGovernor-execute}.\n */\n function execute(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public payable virtual override returns (uint256) {\n uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n ProposalState currentState = state(proposalId);\n require(\n currentState == ProposalState.Succeeded || currentState == ProposalState.Queued,\n \"Governor: proposal not successful\"\n );\n _proposals[proposalId].executed = true;\n\n emit ProposalExecuted(proposalId);\n\n _beforeExecute(proposalId, targets, values, calldatas, descriptionHash);\n _execute(proposalId, targets, values, calldatas, descriptionHash);\n _afterExecute(proposalId, targets, values, calldatas, descriptionHash);\n\n return proposalId;\n }\n\n /**\n * @dev See {IGovernor-cancel}.\n */\n function cancel(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public virtual override returns (uint256) {\n uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n require(state(proposalId) == ProposalState.Pending, \"Governor: too late to cancel\");\n require(_msgSender() == _proposals[proposalId].proposer, \"Governor: only proposer can cancel\");\n return _cancel(targets, values, calldatas, descriptionHash);\n }\n\n /**\n * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism\n */\n function _execute(\n uint256 /* proposalId */,\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 /*descriptionHash*/\n ) internal virtual {\n string memory errorMessage = \"Governor: call reverted without message\";\n for (uint256 i = 0; i < targets.length; ++i) {\n (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);\n AddressUpgradeable.verifyCallResult(success, returndata, errorMessage);\n }\n }\n\n /**\n * @dev Hook before execution is triggered.\n */\n function _beforeExecute(\n uint256 /* proposalId */,\n address[] memory targets,\n uint256[] memory /* values */,\n bytes[] memory calldatas,\n bytes32 /*descriptionHash*/\n ) internal virtual {\n if (_executor() != address(this)) {\n for (uint256 i = 0; i < targets.length; ++i) {\n if (targets[i] == address(this)) {\n _governanceCall.pushBack(keccak256(calldatas[i]));\n }\n }\n }\n }\n\n /**\n * @dev Hook after execution is triggered.\n */\n function _afterExecute(\n uint256 /* proposalId */,\n address[] memory /* targets */,\n uint256[] memory /* values */,\n bytes[] memory /* calldatas */,\n bytes32 /*descriptionHash*/\n ) internal virtual {\n if (_executor() != address(this)) {\n if (!_governanceCall.empty()) {\n _governanceCall.clear();\n }\n }\n }\n\n /**\n * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as\n * canceled to allow distinguishing it from executed proposals.\n *\n * Emits a {IGovernor-ProposalCanceled} event.\n */\n function _cancel(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) internal virtual returns (uint256) {\n uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n ProposalState currentState = state(proposalId);\n\n require(\n currentState != ProposalState.Canceled &&\n currentState != ProposalState.Expired &&\n currentState != ProposalState.Executed,\n \"Governor: proposal not active\"\n );\n _proposals[proposalId].canceled = true;\n\n emit ProposalCanceled(proposalId);\n\n return proposalId;\n }\n\n /**\n * @dev See {IGovernor-getVotes}.\n */\n function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) {\n return _getVotes(account, timepoint, _defaultParams());\n }\n\n /**\n * @dev See {IGovernor-getVotesWithParams}.\n */\n function getVotesWithParams(\n address account,\n uint256 timepoint,\n bytes memory params\n ) public view virtual override returns (uint256) {\n return _getVotes(account, timepoint, params);\n }\n\n /**\n * @dev See {IGovernor-castVote}.\n */\n function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) {\n address voter = _msgSender();\n return _castVote(proposalId, voter, support, \"\");\n }\n\n /**\n * @dev See {IGovernor-castVoteWithReason}.\n */\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) public virtual override returns (uint256) {\n address voter = _msgSender();\n return _castVote(proposalId, voter, support, reason);\n }\n\n /**\n * @dev See {IGovernor-castVoteWithReasonAndParams}.\n */\n function castVoteWithReasonAndParams(\n uint256 proposalId,\n uint8 support,\n string calldata reason,\n bytes memory params\n ) public virtual override returns (uint256) {\n address voter = _msgSender();\n return _castVote(proposalId, voter, support, reason, params);\n }\n\n /**\n * @dev See {IGovernor-castVoteBySig}.\n */\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override returns (uint256) {\n address voter = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))),\n v,\n r,\n s\n );\n return _castVote(proposalId, voter, support, \"\");\n }\n\n /**\n * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}.\n */\n function castVoteWithReasonAndParamsBySig(\n uint256 proposalId,\n uint8 support,\n string calldata reason,\n bytes memory params,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override returns (uint256) {\n address voter = ECDSAUpgradeable.recover(\n _hashTypedDataV4(\n keccak256(\n abi.encode(\n EXTENDED_BALLOT_TYPEHASH,\n proposalId,\n support,\n keccak256(bytes(reason)),\n keccak256(params)\n )\n )\n ),\n v,\n r,\n s\n );\n\n return _castVote(proposalId, voter, support, reason, params);\n }\n\n /**\n * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve\n * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams().\n *\n * Emits a {IGovernor-VoteCast} event.\n */\n function _castVote(\n uint256 proposalId,\n address account,\n uint8 support,\n string memory reason\n ) internal virtual returns (uint256) {\n return _castVote(proposalId, account, support, reason, _defaultParams());\n }\n\n /**\n * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve\n * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function.\n *\n * Emits a {IGovernor-VoteCast} event.\n */\n function _castVote(\n uint256 proposalId,\n address account,\n uint8 support,\n string memory reason,\n bytes memory params\n ) internal virtual returns (uint256) {\n ProposalCore storage proposal = _proposals[proposalId];\n require(state(proposalId) == ProposalState.Active, \"Governor: vote not currently active\");\n\n uint256 weight = _getVotes(account, proposal.voteStart, params);\n _countVote(proposalId, account, support, weight, params);\n\n if (params.length == 0) {\n emit VoteCast(account, proposalId, support, weight, reason);\n } else {\n emit VoteCastWithParams(account, proposalId, support, weight, reason, params);\n }\n\n return weight;\n }\n\n /**\n * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor\n * is some contract other than the governor itself, like when using a timelock, this function can be invoked\n * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake.\n * Note that if the executor is simply the governor itself, use of `relay` is redundant.\n */\n function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance {\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n AddressUpgradeable.verifyCallResult(success, returndata, \"Governor: relay reverted without message\");\n }\n\n /**\n * @dev Address through which the governor executes action. Will be overloaded by module that execute actions\n * through another contract such as a timelock.\n */\n function _executor() internal view virtual returns (address) {\n return address(this);\n }\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155Received}.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /**\n * @dev Check if the proposer is authorized to submit a proposal with the given description.\n *\n * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string\n * (case insensitive), then the submission of this proposal will only be authorized to said address.\n *\n * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure\n * that no other address can submit the same proposal. An attacker would have to either remove or change that part,\n * which would result in a different proposal id.\n *\n * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes:\n * - If the `0x???` part is not a valid hex string.\n * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits.\n * - If it ends with the expected suffix followed by newlines or other whitespace.\n * - If it ends with some other similar suffix, e.g. `#other=abc`.\n * - If it does not end with any such suffix.\n */\n function _isValidDescriptionForProposer(\n address proposer,\n string memory description\n ) internal view virtual returns (bool) {\n uint256 len = bytes(description).length;\n\n // Length is too short to contain a valid proposer suffix\n if (len < 52) {\n return true;\n }\n\n // Extract what would be the `#proposer=0x` marker beginning the suffix\n bytes12 marker;\n assembly {\n // - Start of the string contents in memory = description + 32\n // - First character of the marker = len - 52\n // - Length of \"#proposer=0x0000000000000000000000000000000000000000\" = 52\n // - We read the memory word starting at the first character of the marker:\n // - (description + 32) + (len - 52) = description + (len - 20)\n // - Note: Solidity will ignore anything past the first 12 bytes\n marker := mload(add(description, sub(len, 20)))\n }\n\n // If the marker is not found, there is no proposer suffix to check\n if (marker != bytes12(\"#proposer=0x\")) {\n return true;\n }\n\n // Parse the 40 characters following the marker as uint160\n uint160 recovered = 0;\n for (uint256 i = len - 40; i < len; ++i) {\n (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]);\n // If any of the characters is not a hex digit, ignore the suffix entirely\n if (!isHex) {\n return true;\n }\n recovered = (recovered << 4) | value;\n }\n\n return recovered == uint160(proposer);\n }\n\n /**\n * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in\n * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16`\n */\n function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) {\n uint8 c = uint8(char);\n unchecked {\n // Case 0-9\n if (47 < c && c < 58) {\n return (true, c - 48);\n }\n // Case A-F\n else if (64 < c && c < 71) {\n return (true, c - 55);\n }\n // Case a-f\n else if (96 < c && c < 103) {\n return (true, c - 87);\n }\n // Else: not a hex char\n else {\n return (false, 0);\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/DoubleEndedQueueUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol)\npragma solidity ^0.8.4;\n\nimport \"../math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of\n * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and\n * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that\n * the existing queue contents are left in storage.\n *\n * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be\n * used in storage, and not in memory.\n * ```solidity\n * DoubleEndedQueue.Bytes32Deque queue;\n * ```\n *\n * _Available since v4.6._\n */\nlibrary DoubleEndedQueueUpgradeable {\n /**\n * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.\n */\n error Empty();\n\n /**\n * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.\n */\n error OutOfBounds();\n\n /**\n * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end\n * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely\n * assume that these 128-bit indices will not overflow, and use unchecked arithmetic.\n *\n * Struct members have an underscore prefix indicating that they are \"private\" and should not be read or written to\n * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and\n * lead to unexpected behavior.\n *\n * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at\n * data[end - 1].\n */\n struct Bytes32Deque {\n int128 _begin;\n int128 _end;\n mapping(int128 => bytes32) _data;\n }\n\n /**\n * @dev Inserts an item at the end of the queue.\n */\n function pushBack(Bytes32Deque storage deque, bytes32 value) internal {\n int128 backIndex = deque._end;\n deque._data[backIndex] = value;\n unchecked {\n deque._end = backIndex + 1;\n }\n }\n\n /**\n * @dev Removes the item at the end of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n value = deque._data[backIndex];\n delete deque._data[backIndex];\n deque._end = backIndex;\n }\n\n /**\n * @dev Inserts an item at the beginning of the queue.\n */\n function pushFront(Bytes32Deque storage deque, bytes32 value) internal {\n int128 frontIndex;\n unchecked {\n frontIndex = deque._begin - 1;\n }\n deque._data[frontIndex] = value;\n deque._begin = frontIndex;\n }\n\n /**\n * @dev Removes the item at the beginning of the queue and returns it.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n value = deque._data[frontIndex];\n delete deque._data[frontIndex];\n unchecked {\n deque._begin = frontIndex + 1;\n }\n }\n\n /**\n * @dev Returns the item at the beginning of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 frontIndex = deque._begin;\n return deque._data[frontIndex];\n }\n\n /**\n * @dev Returns the item at the end of the queue.\n *\n * Reverts with `Empty` if the queue is empty.\n */\n function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {\n if (empty(deque)) revert Empty();\n int128 backIndex;\n unchecked {\n backIndex = deque._end - 1;\n }\n return deque._data[backIndex];\n }\n\n /**\n * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at\n * `length(deque) - 1`.\n *\n * Reverts with `OutOfBounds` if the index is out of bounds.\n */\n function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {\n // int256(deque._begin) is a safe upcast\n int128 idx = SafeCastUpgradeable.toInt128(int256(deque._begin) + SafeCastUpgradeable.toInt256(index));\n if (idx >= deque._end) revert OutOfBounds();\n return deque._data[idx];\n }\n\n /**\n * @dev Resets the queue back to being empty.\n *\n * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses\n * out on potential gas refunds.\n */\n function clear(Bytes32Deque storage deque) internal {\n deque._begin = 0;\n deque._end = 0;\n }\n\n /**\n * @dev Returns the number of items in the queue.\n */\n function length(Bytes32Deque storage deque) internal view returns (uint256) {\n // The interface preserves the invariant that begin <= end so we assume this will not overflow.\n // We also assume there are at most int256.max items in the queue.\n unchecked {\n return uint256(int256(deque._end) - int256(deque._begin));\n }\n }\n\n /**\n * @dev Returns true if the queue is empty.\n */\n function empty(Bytes32Deque storage deque) internal view returns (bool) {\n return deque._end <= deque._begin;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/IGovernorUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../interfaces/IERC165Upgradeable.sol\";\nimport \"../interfaces/IERC6372Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Interface of the {Governor} core.\n *\n * _Available since v4.3._\n */\nabstract contract IGovernorUpgradeable is Initializable, IERC165Upgradeable, IERC6372Upgradeable {\n function __IGovernor_init() internal onlyInitializing {\n }\n\n function __IGovernor_init_unchained() internal onlyInitializing {\n }\n enum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n }\n\n /**\n * @dev Emitted when a proposal is created.\n */\n event ProposalCreated(\n uint256 proposalId,\n address proposer,\n address[] targets,\n uint256[] values,\n string[] signatures,\n bytes[] calldatas,\n uint256 voteStart,\n uint256 voteEnd,\n string description\n );\n\n /**\n * @dev Emitted when a proposal is canceled.\n */\n event ProposalCanceled(uint256 proposalId);\n\n /**\n * @dev Emitted when a proposal is executed.\n */\n event ProposalExecuted(uint256 proposalId);\n\n /**\n * @dev Emitted when a vote is cast without params.\n *\n * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.\n */\n event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);\n\n /**\n * @dev Emitted when a vote is cast with params.\n *\n * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used.\n * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used.\n */\n event VoteCastWithParams(\n address indexed voter,\n uint256 proposalId,\n uint8 support,\n uint256 weight,\n string reason,\n bytes params\n );\n\n /**\n * @notice module:core\n * @dev Name of the governor instance (used in building the ERC712 domain separator).\n */\n function name() public view virtual returns (string memory);\n\n /**\n * @notice module:core\n * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: \"1\"\n */\n function version() public view virtual returns (string memory);\n\n /**\n * @notice module:core\n * @dev See {IERC6372}\n */\n function clock() public view virtual override returns (uint48);\n\n /**\n * @notice module:core\n * @dev See EIP-6372.\n */\n // solhint-disable-next-line func-name-mixedcase\n function CLOCK_MODE() public view virtual override returns (string memory);\n\n /**\n * @notice module:voting\n * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to\n * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of\n * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.\n *\n * There are 2 standard keys: `support` and `quorum`.\n *\n * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`.\n * - `quorum=bravo` means that only For votes are counted towards quorum.\n * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum.\n *\n * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique\n * name that describes the behavior. For example:\n *\n * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain.\n * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote.\n *\n * NOTE: The string can be decoded by the standard\n * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`]\n * JavaScript class.\n */\n // solhint-disable-next-line func-name-mixedcase\n function COUNTING_MODE() public view virtual returns (string memory);\n\n /**\n * @notice module:core\n * @dev Hashing function used to (re)build the proposal id from the proposal details..\n */\n function hashProposal(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public pure virtual returns (uint256);\n\n /**\n * @notice module:core\n * @dev Current state of a proposal, following Compound's convention\n */\n function state(uint256 proposalId) public view virtual returns (ProposalState);\n\n /**\n * @notice module:core\n * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the\n * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the\n * following block.\n */\n function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);\n\n /**\n * @notice module:core\n * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is\n * possible to cast a vote during this block.\n */\n function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);\n\n /**\n * @notice module:core\n * @dev The account that created a proposal.\n */\n function proposalProposer(uint256 proposalId) public view virtual returns (address);\n\n /**\n * @notice module:user-config\n * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends\n * on the clock (see EIP-6372) this contract uses.\n *\n * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a\n * proposal starts.\n */\n function votingDelay() public view virtual returns (uint256);\n\n /**\n * @notice module:user-config\n * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock\n * (see EIP-6372) this contract uses.\n *\n * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting\n * duration compared to the voting delay.\n */\n function votingPeriod() public view virtual returns (uint256);\n\n /**\n * @notice module:user-config\n * @dev Minimum number of cast voted required for a proposal to be successful.\n *\n * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the\n * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}).\n */\n function quorum(uint256 timepoint) public view virtual returns (uint256);\n\n /**\n * @notice module:reputation\n * @dev Voting power of an `account` at a specific `timepoint`.\n *\n * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or\n * multiple), {ERC20Votes} tokens.\n */\n function getVotes(address account, uint256 timepoint) public view virtual returns (uint256);\n\n /**\n * @notice module:reputation\n * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters.\n */\n function getVotesWithParams(\n address account,\n uint256 timepoint,\n bytes memory params\n ) public view virtual returns (uint256);\n\n /**\n * @notice module:voting\n * @dev Returns whether `account` has cast a vote on `proposalId`.\n */\n function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);\n\n /**\n * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a\n * duration specified by {IGovernor-votingPeriod}.\n *\n * Emits a {ProposalCreated} event.\n */\n function propose(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n string memory description\n ) public virtual returns (uint256 proposalId);\n\n /**\n * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the\n * deadline to be reached.\n *\n * Emits a {ProposalExecuted} event.\n *\n * Note: some module can modify the requirements for execution, for example by adding an additional timelock.\n */\n function execute(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public payable virtual returns (uint256 proposalId);\n\n /**\n * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e.\n * before the vote starts.\n *\n * Emits a {ProposalCanceled} event.\n */\n function cancel(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public virtual returns (uint256 proposalId);\n\n /**\n * @dev Cast a vote\n *\n * Emits a {VoteCast} event.\n */\n function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance);\n\n /**\n * @dev Cast a vote with a reason\n *\n * Emits a {VoteCast} event.\n */\n function castVoteWithReason(\n uint256 proposalId,\n uint8 support,\n string calldata reason\n ) public virtual returns (uint256 balance);\n\n /**\n * @dev Cast a vote with a reason and additional encoded parameters\n *\n * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.\n */\n function castVoteWithReasonAndParams(\n uint256 proposalId,\n uint8 support,\n string calldata reason,\n bytes memory params\n ) public virtual returns (uint256 balance);\n\n /**\n * @dev Cast a vote using the user's cryptographic signature.\n *\n * Emits a {VoteCast} event.\n */\n function castVoteBySig(\n uint256 proposalId,\n uint8 support,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual returns (uint256 balance);\n\n /**\n * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature.\n *\n * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params.\n */\n function castVoteWithReasonAndParamsBySig(\n uint256 proposalId,\n uint8 support,\n string calldata reason,\n bytes memory params,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual returns (uint256 balance);\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n" + }, + "contracts/treasury/LivepeerGovernor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol\";\n\nimport \"../bonding/libraries/EarningsPool.sol\";\nimport \"../bonding/libraries/EarningsPoolLIP36.sol\";\n\nimport \"../ManagerProxyTarget.sol\";\nimport \"../IController.sol\";\nimport \"../rounds/IRoundsManager.sol\";\nimport \"./GovernorCountingOverridable.sol\";\nimport \"./Treasury.sol\";\n\n/**\n * @title LivepeerGovernor\n * @notice Core contract for Livepeer governance, starting as the treasury governor.\n * @dev If we ever add fields to this class or more extensions, make sure to add a storage gap to our custom\n * GovernorCountingOverridable extension.\n */\ncontract LivepeerGovernor is\n ManagerProxyTarget,\n Initializable,\n GovernorUpgradeable,\n GovernorSettingsUpgradeable,\n GovernorTimelockControlUpgradeable,\n GovernorVotesUpgradeable,\n GovernorVotesQuorumFractionUpgradeable,\n GovernorCountingOverridable\n{\n /**\n * @notice TreasuryGovernor constructor. Only invokes constructor of base Manager contract with provided Controller.\n * @dev This constructor will not initialize any state variables besides `controller`. The `initialize` function\n * must be called through the proxy after construction to initialize the contract's state in the proxy contract.\n * @param _controller Address of Controller that this contract will be registered with\n */\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(address _controller) Manager(_controller) {\n _disableInitializers();\n }\n\n /**\n * Initializes the LivepeerGovernor instance. This requires the following contracts to have already been deployed\n * and registered on the controller:\n * - \"Treasury\"\n * - \"BondingVotes\"\n * - \"PollCreator\"\n */\n function initialize(\n uint256 initialVotingDelay,\n uint256 initialVotingPeriod,\n uint256 initialProposalThreshold,\n uint256 initialQuorum,\n uint256 quota\n ) public initializer {\n __Governor_init(\"LivepeerGovernor\");\n __GovernorSettings_init(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);\n __GovernorTimelockControl_init(treasury());\n\n // The GovernorVotes module will hold a fixed reference to the votes contract. If we ever change its address we\n // need to call the {bumpGovernorVotesTokenAddress} function to update it in here as well.\n __GovernorVotes_init(votes());\n\n __GovernorVotesQuorumFraction_init(initialQuorum);\n\n __GovernorCountingOverridable_init(quota);\n }\n\n /**\n * @dev Overrides the quorum denominator from the GovernorVotesQuorumFractionUpgradeable extension. We use\n * MathUtils.PERC_DIVISOR so that our quorum numerator is a valid MathUtils fraction.\n */\n function quorumDenominator() public view virtual override returns (uint256) {\n return MathUtils.PERC_DIVISOR;\n }\n\n /**\n * @dev See {GovernorCountingOverridable-votes}.\n */\n function votes() public view override returns (IVotes) {\n return bondingVotes();\n }\n\n /**\n * @dev This should be called if we ever change the address of the BondingVotes contract. Not a normal flow, but its\n * address could still eventually change in the controller so we provide this function as a future-proof commodity.\n * This is callable by anyone because it always fetches the current address from the controller, so not exploitable.\n */\n function bumpGovernorVotesTokenAddress() external {\n token = votes();\n }\n\n /**\n * @dev Returns the BondingVotes contract address from the controller.\n */\n function bondingVotes() internal view returns (IVotes) {\n return IVotes(controller.getContract(keccak256(\"BondingVotes\")));\n }\n\n /**\n * @dev Returns the Treasury contract address from the controller.\n */\n function treasury() internal view returns (Treasury) {\n return Treasury(payable(controller.getContract(keccak256(\"Treasury\"))));\n }\n\n // The following functions are overrides required by Solidity.\n\n function proposalThreshold()\n public\n view\n override(GovernorUpgradeable, GovernorSettingsUpgradeable)\n returns (uint256)\n {\n return super.proposalThreshold();\n }\n\n function state(uint256 proposalId)\n public\n view\n override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n returns (ProposalState)\n {\n return super.state(proposalId);\n }\n\n function _execute(\n uint256 proposalId,\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {\n super._execute(proposalId, targets, values, calldatas, descriptionHash);\n }\n\n function _cancel(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {\n return super._cancel(targets, values, calldatas, descriptionHash);\n }\n\n function _executor()\n internal\n view\n override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n returns (address)\n {\n return super._executor();\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../GovernorUpgradeable.sol\";\nimport \"../../interfaces/IERC5805Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.\n *\n * _Available since v4.3._\n *\n * @custom:storage-size 51\n */\nabstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable {\n IERC5805Upgradeable public token;\n\n function __GovernorVotes_init(IVotesUpgradeable tokenAddress) internal onlyInitializing {\n __GovernorVotes_init_unchained(tokenAddress);\n }\n\n function __GovernorVotes_init_unchained(IVotesUpgradeable tokenAddress) internal onlyInitializing {\n token = IERC5805Upgradeable(address(tokenAddress));\n }\n\n /**\n * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token\n * does not implement EIP-6372.\n */\n function clock() public view virtual override returns (uint48) {\n try token.clock() returns (uint48 timepoint) {\n return timepoint;\n } catch {\n return SafeCastUpgradeable.toUint48(block.number);\n }\n }\n\n /**\n * @dev Machine-readable description of the clock as specified in EIP-6372.\n */\n // solhint-disable-next-line func-name-mixedcase\n function CLOCK_MODE() public view virtual override returns (string memory) {\n try token.CLOCK_MODE() returns (string memory clockmode) {\n return clockmode;\n } catch {\n return \"mode=blocknumber&from=default\";\n }\n }\n\n /**\n * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}).\n */\n function _getVotes(\n address account,\n uint256 timepoint,\n bytes memory /*params*/\n ) internal view virtual override returns (uint256) {\n return token.getPastVotes(account, timepoint);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotesQuorumFraction.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./GovernorVotesUpgradeable.sol\";\nimport \"../../utils/CheckpointsUpgradeable.sol\";\nimport \"../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a\n * fraction of the total supply.\n *\n * _Available since v4.3._\n */\nabstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, GovernorVotesUpgradeable {\n using CheckpointsUpgradeable for CheckpointsUpgradeable.Trace224;\n\n uint256 private _quorumNumerator; // DEPRECATED in favor of _quorumNumeratorHistory\n\n /// @custom:oz-retyped-from Checkpoints.History\n CheckpointsUpgradeable.Trace224 private _quorumNumeratorHistory;\n\n event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);\n\n /**\n * @dev Initialize quorum as a fraction of the token's total supply.\n *\n * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is\n * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be\n * customized by overriding {quorumDenominator}.\n */\n function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing {\n __GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue);\n }\n\n function __GovernorVotesQuorumFraction_init_unchained(uint256 quorumNumeratorValue) internal onlyInitializing {\n _updateQuorumNumerator(quorumNumeratorValue);\n }\n\n /**\n * @dev Returns the current quorum numerator. See {quorumDenominator}.\n */\n function quorumNumerator() public view virtual returns (uint256) {\n return _quorumNumeratorHistory._checkpoints.length == 0 ? _quorumNumerator : _quorumNumeratorHistory.latest();\n }\n\n /**\n * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}.\n */\n function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) {\n // If history is empty, fallback to old storage\n uint256 length = _quorumNumeratorHistory._checkpoints.length;\n if (length == 0) {\n return _quorumNumerator;\n }\n\n // Optimistic search, check the latest checkpoint\n CheckpointsUpgradeable.Checkpoint224 memory latest = _quorumNumeratorHistory._checkpoints[length - 1];\n if (latest._key <= timepoint) {\n return latest._value;\n }\n\n // Otherwise, do the binary search\n return _quorumNumeratorHistory.upperLookupRecent(SafeCastUpgradeable.toUint32(timepoint));\n }\n\n /**\n * @dev Returns the quorum denominator. Defaults to 100, but may be overridden.\n */\n function quorumDenominator() public view virtual returns (uint256) {\n return 100;\n }\n\n /**\n * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`.\n */\n function quorum(uint256 timepoint) public view virtual override returns (uint256) {\n return (token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator();\n }\n\n /**\n * @dev Changes the quorum numerator.\n *\n * Emits a {QuorumNumeratorUpdated} event.\n *\n * Requirements:\n *\n * - Must be called through a governance proposal.\n * - New numerator must be smaller or equal to the denominator.\n */\n function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {\n _updateQuorumNumerator(newQuorumNumerator);\n }\n\n /**\n * @dev Changes the quorum numerator.\n *\n * Emits a {QuorumNumeratorUpdated} event.\n *\n * Requirements:\n *\n * - New numerator must be smaller or equal to the denominator.\n */\n function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {\n require(\n newQuorumNumerator <= quorumDenominator(),\n \"GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator\"\n );\n\n uint256 oldQuorumNumerator = quorumNumerator();\n\n // Make sure we keep track of the original numerator in contracts upgraded from a version without checkpoints.\n if (oldQuorumNumerator != 0 && _quorumNumeratorHistory._checkpoints.length == 0) {\n _quorumNumeratorHistory._checkpoints.push(\n CheckpointsUpgradeable.Checkpoint224({_key: 0, _value: SafeCastUpgradeable.toUint224(oldQuorumNumerator)})\n );\n }\n\n // Set new quorum for future proposals\n _quorumNumeratorHistory.push(SafeCastUpgradeable.toUint32(clock()), SafeCastUpgradeable.toUint224(newQuorumNumerator));\n\n emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorSettings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../GovernorUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} for settings updatable through governance.\n *\n * _Available since v4.4._\n */\nabstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradeable {\n uint256 private _votingDelay;\n uint256 private _votingPeriod;\n uint256 private _proposalThreshold;\n\n event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);\n event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);\n event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);\n\n /**\n * @dev Initialize the governance parameters.\n */\n function __GovernorSettings_init(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {\n __GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);\n }\n\n function __GovernorSettings_init_unchained(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {\n _setVotingDelay(initialVotingDelay);\n _setVotingPeriod(initialVotingPeriod);\n _setProposalThreshold(initialProposalThreshold);\n }\n\n /**\n * @dev See {IGovernor-votingDelay}.\n */\n function votingDelay() public view virtual override returns (uint256) {\n return _votingDelay;\n }\n\n /**\n * @dev See {IGovernor-votingPeriod}.\n */\n function votingPeriod() public view virtual override returns (uint256) {\n return _votingPeriod;\n }\n\n /**\n * @dev See {Governor-proposalThreshold}.\n */\n function proposalThreshold() public view virtual override returns (uint256) {\n return _proposalThreshold;\n }\n\n /**\n * @dev Update the voting delay. This operation can only be performed through a governance proposal.\n *\n * Emits a {VotingDelaySet} event.\n */\n function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance {\n _setVotingDelay(newVotingDelay);\n }\n\n /**\n * @dev Update the voting period. This operation can only be performed through a governance proposal.\n *\n * Emits a {VotingPeriodSet} event.\n */\n function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance {\n _setVotingPeriod(newVotingPeriod);\n }\n\n /**\n * @dev Update the proposal threshold. This operation can only be performed through a governance proposal.\n *\n * Emits a {ProposalThresholdSet} event.\n */\n function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {\n _setProposalThreshold(newProposalThreshold);\n }\n\n /**\n * @dev Internal setter for the voting delay.\n *\n * Emits a {VotingDelaySet} event.\n */\n function _setVotingDelay(uint256 newVotingDelay) internal virtual {\n emit VotingDelaySet(_votingDelay, newVotingDelay);\n _votingDelay = newVotingDelay;\n }\n\n /**\n * @dev Internal setter for the voting period.\n *\n * Emits a {VotingPeriodSet} event.\n */\n function _setVotingPeriod(uint256 newVotingPeriod) internal virtual {\n // voting period must be at least one block long\n require(newVotingPeriod > 0, \"GovernorSettings: voting period too low\");\n emit VotingPeriodSet(_votingPeriod, newVotingPeriod);\n _votingPeriod = newVotingPeriod;\n }\n\n /**\n * @dev Internal setter for the proposal threshold.\n *\n * Emits a {ProposalThresholdSet} event.\n */\n function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {\n emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold);\n _proposalThreshold = newProposalThreshold;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorTimelockControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IGovernorTimelockUpgradeable.sol\";\nimport \"../GovernorUpgradeable.sol\";\nimport \"../TimelockControllerUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a\n * delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The\n * {Governor} needs the proposer (and ideally the executor) roles for the {Governor} to work properly.\n *\n * Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,\n * the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be\n * inaccessible.\n *\n * WARNING: Setting up the TimelockController to have additional proposers besides the governor is very risky, as it\n * grants them powers that they must be trusted or known not to use: 1) {onlyGovernance} functions like {relay} are\n * available to them through the timelock, and 2) approved governance proposals can be blocked by them, effectively\n * executing a Denial of Service attack. This risk will be mitigated in a future release.\n *\n * _Available since v4.3._\n */\nabstract contract GovernorTimelockControlUpgradeable is Initializable, IGovernorTimelockUpgradeable, GovernorUpgradeable {\n TimelockControllerUpgradeable private _timelock;\n mapping(uint256 => bytes32) private _timelockIds;\n\n /**\n * @dev Emitted when the timelock controller used for proposal execution is modified.\n */\n event TimelockChange(address oldTimelock, address newTimelock);\n\n /**\n * @dev Set the timelock.\n */\n function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {\n __GovernorTimelockControl_init_unchained(timelockAddress);\n }\n\n function __GovernorTimelockControl_init_unchained(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {\n _updateTimelock(timelockAddress);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, GovernorUpgradeable) returns (bool) {\n return interfaceId == type(IGovernorTimelockUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Overridden version of the {Governor-state} function with added support for the `Queued` state.\n */\n function state(uint256 proposalId) public view virtual override(IGovernorUpgradeable, GovernorUpgradeable) returns (ProposalState) {\n ProposalState currentState = super.state(proposalId);\n\n if (currentState != ProposalState.Succeeded) {\n return currentState;\n }\n\n // core tracks execution, so we just have to check if successful proposal have been queued.\n bytes32 queueid = _timelockIds[proposalId];\n if (queueid == bytes32(0)) {\n return currentState;\n } else if (_timelock.isOperationDone(queueid)) {\n return ProposalState.Executed;\n } else if (_timelock.isOperationPending(queueid)) {\n return ProposalState.Queued;\n } else {\n return ProposalState.Canceled;\n }\n }\n\n /**\n * @dev Public accessor to check the address of the timelock\n */\n function timelock() public view virtual override returns (address) {\n return address(_timelock);\n }\n\n /**\n * @dev Public accessor to check the eta of a queued proposal\n */\n function proposalEta(uint256 proposalId) public view virtual override returns (uint256) {\n uint256 eta = _timelock.getTimestamp(_timelockIds[proposalId]);\n return eta == 1 ? 0 : eta; // _DONE_TIMESTAMP (1) should be replaced with a 0 value\n }\n\n /**\n * @dev Function to queue a proposal to the timelock.\n */\n function queue(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public virtual override returns (uint256) {\n uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash);\n\n require(state(proposalId) == ProposalState.Succeeded, \"Governor: proposal not successful\");\n\n uint256 delay = _timelock.getMinDelay();\n _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);\n _timelock.scheduleBatch(targets, values, calldatas, 0, descriptionHash, delay);\n\n emit ProposalQueued(proposalId, block.timestamp + delay);\n\n return proposalId;\n }\n\n /**\n * @dev Overridden execute function that run the already queued proposal through the timelock.\n */\n function _execute(\n uint256 /* proposalId */,\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) internal virtual override {\n _timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, descriptionHash);\n }\n\n /**\n * @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it as already\n * been queued.\n */\n // This function can reenter through the external call to the timelock, but we assume the timelock is trusted and\n // well behaved (according to TimelockController) and this will not happen.\n // slither-disable-next-line reentrancy-no-eth\n function _cancel(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) internal virtual override returns (uint256) {\n uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);\n\n if (_timelockIds[proposalId] != 0) {\n _timelock.cancel(_timelockIds[proposalId]);\n delete _timelockIds[proposalId];\n }\n\n return proposalId;\n }\n\n /**\n * @dev Address through which the governor executes action. In this case, the timelock.\n */\n function _executor() internal view virtual override returns (address) {\n return address(_timelock);\n }\n\n /**\n * @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates\n * must be proposed, scheduled, and executed through governance proposals.\n *\n * CAUTION: It is not recommended to change the timelock while there are other queued governance proposals.\n */\n function updateTimelock(TimelockControllerUpgradeable newTimelock) external virtual onlyGovernance {\n _updateTimelock(newTimelock);\n }\n\n function _updateTimelock(TimelockControllerUpgradeable newTimelock) private {\n emit TimelockChange(address(_timelock), address(newTimelock));\n _timelock = newTimelock;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol\";\n\n/**\n * @title Treasury\n * @notice Holder of the treasury and executor of proposals for the LivepeerGovernor.\n * @dev This was only really needed because TimelockControllerUpgradeable does not expose a public initializer, so we\n * need to inherit and expose the initialization function here.\n *\n * Even though this contract is upgradeable to fit with the rest of the contracts that expect upgradeable instances, it\n * is not used with a proxy, so we don't need to disable initializers in the constructor.\n */\ncontract Treasury is Initializable, TimelockControllerUpgradeable {\n function initialize(\n uint256 minDelay,\n address[] memory proposers,\n address[] memory executors,\n address admin\n ) external initializer {\n __TimelockController_init(minDelay, proposers, executors, admin);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev This library defines the `History` struct, for checkpointing values as they change at different points in\n * time, and later looking up past values by block number. See {Votes} as an example.\n *\n * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new\n * checkpoint for the current transaction block using the {push} function.\n *\n * _Available since v4.5._\n */\nlibrary CheckpointsUpgradeable {\n struct History {\n Checkpoint[] _checkpoints;\n }\n\n struct Checkpoint {\n uint32 _blockNumber;\n uint224 _value;\n }\n\n /**\n * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the\n * block, the requested block number must be in the past, excluding the current block.\n */\n function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n uint256 len = self._checkpoints.length;\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched\n * checkpoint is probably \"recent\", defined as being among the last sqrt(N) checkpoints where N is the number of\n * checkpoints.\n */\n function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n uint256 len = self._checkpoints.length;\n\n uint256 low = 0;\n uint256 high = len;\n\n if (len > 5) {\n uint256 mid = len - MathUpgradeable.sqrt(len);\n if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.\n *\n * Returns previous value and new value.\n */\n function push(History storage self, uint256 value) internal returns (uint256, uint256) {\n return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value));\n }\n\n /**\n * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will\n * be set to `op(latest, delta)`.\n *\n * Returns previous value and new value.\n */\n function push(\n History storage self,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) internal returns (uint256, uint256) {\n return push(self, op(latest(self), delta));\n }\n\n /**\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n */\n function latest(History storage self) internal view returns (uint224) {\n uint256 pos = self._checkpoints.length;\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n * in the most recent checkpoint.\n */\n function latestCheckpoint(\n History storage self\n ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {\n uint256 pos = self._checkpoints.length;\n if (pos == 0) {\n return (false, 0, 0);\n } else {\n Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n return (true, ckpt._blockNumber, ckpt._value);\n }\n }\n\n /**\n * @dev Returns the number of checkpoint.\n */\n function length(History storage self) internal view returns (uint256) {\n return self._checkpoints.length;\n }\n\n /**\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n * or by updating the last one.\n */\n function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n uint256 pos = self.length;\n\n if (pos > 0) {\n // Copying to memory is important here.\n Checkpoint memory last = _unsafeAccess(self, pos - 1);\n\n // Checkpoint keys must be non-decreasing.\n require(last._blockNumber <= key, \"Checkpoint: decreasing keys\");\n\n // Update or push new checkpoint\n if (last._blockNumber == key) {\n _unsafeAccess(self, pos - 1)._value = value;\n } else {\n self.push(Checkpoint({_blockNumber: key, _value: value}));\n }\n return (last._value, value);\n } else {\n self.push(Checkpoint({_blockNumber: key, _value: value}));\n return (0, value);\n }\n }\n\n /**\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _upperBinaryLookup(\n Checkpoint[] storage self,\n uint32 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._blockNumber > key) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n return high;\n }\n\n /**\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _lowerBinaryLookup(\n Checkpoint[] storage self,\n uint32 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._blockNumber < key) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n\n /**\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n */\n function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {\n assembly {\n mstore(0, self.slot)\n result.slot := add(keccak256(0, 0x20), pos)\n }\n }\n\n struct Trace224 {\n Checkpoint224[] _checkpoints;\n }\n\n struct Checkpoint224 {\n uint32 _key;\n uint224 _value;\n }\n\n /**\n * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\n *\n * Returns previous value and new value.\n */\n function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\n return _insert(self._checkpoints, key, value);\n }\n\n /**\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n */\n function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n uint256 len = self._checkpoints.length;\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n }\n\n /**\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n */\n function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n uint256 len = self._checkpoints.length;\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n *\n * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n */\n function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\n uint256 len = self._checkpoints.length;\n\n uint256 low = 0;\n uint256 high = len;\n\n if (len > 5) {\n uint256 mid = len - MathUpgradeable.sqrt(len);\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n */\n function latest(Trace224 storage self) internal view returns (uint224) {\n uint256 pos = self._checkpoints.length;\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n * in the most recent checkpoint.\n */\n function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\n uint256 pos = self._checkpoints.length;\n if (pos == 0) {\n return (false, 0, 0);\n } else {\n Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n return (true, ckpt._key, ckpt._value);\n }\n }\n\n /**\n * @dev Returns the number of checkpoint.\n */\n function length(Trace224 storage self) internal view returns (uint256) {\n return self._checkpoints.length;\n }\n\n /**\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n * or by updating the last one.\n */\n function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n uint256 pos = self.length;\n\n if (pos > 0) {\n // Copying to memory is important here.\n Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\n\n // Checkpoint keys must be non-decreasing.\n require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n // Update or push new checkpoint\n if (last._key == key) {\n _unsafeAccess(self, pos - 1)._value = value;\n } else {\n self.push(Checkpoint224({_key: key, _value: value}));\n }\n return (last._value, value);\n } else {\n self.push(Checkpoint224({_key: key, _value: value}));\n return (0, value);\n }\n }\n\n /**\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _upperBinaryLookup(\n Checkpoint224[] storage self,\n uint32 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._key > key) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n return high;\n }\n\n /**\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _lowerBinaryLookup(\n Checkpoint224[] storage self,\n uint32 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._key < key) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n\n /**\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n */\n function _unsafeAccess(\n Checkpoint224[] storage self,\n uint256 pos\n ) private pure returns (Checkpoint224 storage result) {\n assembly {\n mstore(0, self.slot)\n result.slot := add(keccak256(0, 0x20), pos)\n }\n }\n\n struct Trace160 {\n Checkpoint160[] _checkpoints;\n }\n\n struct Checkpoint160 {\n uint96 _key;\n uint160 _value;\n }\n\n /**\n * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\n *\n * Returns previous value and new value.\n */\n function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\n return _insert(self._checkpoints, key, value);\n }\n\n /**\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n */\n function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n uint256 len = self._checkpoints.length;\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n }\n\n /**\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n */\n function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n uint256 len = self._checkpoints.length;\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n *\n * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n */\n function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\n uint256 len = self._checkpoints.length;\n\n uint256 low = 0;\n uint256 high = len;\n\n if (len > 5) {\n uint256 mid = len - MathUpgradeable.sqrt(len);\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n */\n function latest(Trace160 storage self) internal view returns (uint160) {\n uint256 pos = self._checkpoints.length;\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n }\n\n /**\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n * in the most recent checkpoint.\n */\n function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\n uint256 pos = self._checkpoints.length;\n if (pos == 0) {\n return (false, 0, 0);\n } else {\n Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n return (true, ckpt._key, ckpt._value);\n }\n }\n\n /**\n * @dev Returns the number of checkpoint.\n */\n function length(Trace160 storage self) internal view returns (uint256) {\n return self._checkpoints.length;\n }\n\n /**\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n * or by updating the last one.\n */\n function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\n uint256 pos = self.length;\n\n if (pos > 0) {\n // Copying to memory is important here.\n Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\n\n // Checkpoint keys must be non-decreasing.\n require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n // Update or push new checkpoint\n if (last._key == key) {\n _unsafeAccess(self, pos - 1)._value = value;\n } else {\n self.push(Checkpoint160({_key: key, _value: value}));\n }\n return (last._value, value);\n } else {\n self.push(Checkpoint160({_key: key, _value: value}));\n return (0, value);\n }\n }\n\n /**\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _upperBinaryLookup(\n Checkpoint160[] storage self,\n uint96 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._key > key) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n return high;\n }\n\n /**\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n *\n * WARNING: `high` should not be greater than the array's length.\n */\n function _lowerBinaryLookup(\n Checkpoint160[] storage self,\n uint96 key,\n uint256 low,\n uint256 high\n ) private view returns (uint256) {\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (_unsafeAccess(self, mid)._key < key) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n\n /**\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n */\n function _unsafeAccess(\n Checkpoint160[] storage self,\n uint256 pos\n ) private pure returns (Checkpoint160 storage result) {\n assembly {\n mstore(0, self.slot)\n result.slot := add(keccak256(0, 0x20), pos)\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/extensions/IGovernorTimelockUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IGovernorUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the {IGovernor} for timelock supporting modules.\n *\n * _Available since v4.3._\n */\nabstract contract IGovernorTimelockUpgradeable is Initializable, IGovernorUpgradeable {\n function __IGovernorTimelock_init() internal onlyInitializing {\n }\n\n function __IGovernorTimelock_init_unchained() internal onlyInitializing {\n }\n event ProposalQueued(uint256 proposalId, uint256 eta);\n\n function timelock() public view virtual returns (address);\n\n function proposalEta(uint256 proposalId) public view virtual returns (uint256);\n\n function queue(\n address[] memory targets,\n uint256[] memory values,\n bytes[] memory calldatas,\n bytes32 descriptionHash\n ) public virtual returns (uint256 proposalId);\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../access/AccessControlUpgradeable.sol\";\nimport \"../token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"../token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which acts as a timelocked controller. When set as the\n * owner of an `Ownable` smart contract, it enforces a timelock on all\n * `onlyOwner` maintenance operations. This gives time for users of the\n * controlled contract to exit before a potentially dangerous maintenance\n * operation is applied.\n *\n * By default, this contract is self administered, meaning administration tasks\n * have to go through the timelock process. The proposer (resp executor) role\n * is in charge of proposing (resp executing) operations. A common use case is\n * to position this {TimelockController} as the owner of a smart contract, with\n * a multisig or a DAO as the sole proposer.\n *\n * _Available since v3.3._\n */\ncontract TimelockControllerUpgradeable is Initializable, AccessControlUpgradeable, IERC721ReceiverUpgradeable, IERC1155ReceiverUpgradeable {\n bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256(\"TIMELOCK_ADMIN_ROLE\");\n bytes32 public constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n bytes32 public constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n bytes32 public constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n uint256 internal constant _DONE_TIMESTAMP = uint256(1);\n\n mapping(bytes32 => uint256) private _timestamps;\n uint256 private _minDelay;\n\n /**\n * @dev Emitted when a call is scheduled as part of operation `id`.\n */\n event CallScheduled(\n bytes32 indexed id,\n uint256 indexed index,\n address target,\n uint256 value,\n bytes data,\n bytes32 predecessor,\n uint256 delay\n );\n\n /**\n * @dev Emitted when a call is performed as part of operation `id`.\n */\n event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);\n\n /**\n * @dev Emitted when new proposal is scheduled with non-zero salt.\n */\n event CallSalt(bytes32 indexed id, bytes32 salt);\n\n /**\n * @dev Emitted when operation `id` is cancelled.\n */\n event Cancelled(bytes32 indexed id);\n\n /**\n * @dev Emitted when the minimum delay for future operations is modified.\n */\n event MinDelayChange(uint256 oldDuration, uint256 newDuration);\n\n /**\n * @dev Initializes the contract with the following parameters:\n *\n * - `minDelay`: initial minimum delay for operations\n * - `proposers`: accounts to be granted proposer and canceller roles\n * - `executors`: accounts to be granted executor role\n * - `admin`: optional account to be granted admin role; disable with zero address\n *\n * IMPORTANT: The optional admin can aid with initial configuration of roles after deployment\n * without being subject to delay, but this role should be subsequently renounced in favor of\n * administration through timelocked proposals. Previous versions of this contract would assign\n * this admin to the deployer automatically and should be renounced as well.\n */\n function __TimelockController_init(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {\n __TimelockController_init_unchained(minDelay, proposers, executors, admin);\n }\n\n function __TimelockController_init_unchained(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {\n _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);\n _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE);\n\n // self administration\n _setupRole(TIMELOCK_ADMIN_ROLE, address(this));\n\n // optional admin\n if (admin != address(0)) {\n _setupRole(TIMELOCK_ADMIN_ROLE, admin);\n }\n\n // register proposers and cancellers\n for (uint256 i = 0; i < proposers.length; ++i) {\n _setupRole(PROPOSER_ROLE, proposers[i]);\n _setupRole(CANCELLER_ROLE, proposers[i]);\n }\n\n // register executors\n for (uint256 i = 0; i < executors.length; ++i) {\n _setupRole(EXECUTOR_ROLE, executors[i]);\n }\n\n _minDelay = minDelay;\n emit MinDelayChange(0, minDelay);\n }\n\n /**\n * @dev Modifier to make a function callable only by a certain role. In\n * addition to checking the sender's role, `address(0)` 's role is also\n * considered. Granting a role to `address(0)` is equivalent to enabling\n * this role for everyone.\n */\n modifier onlyRoleOrOpenRole(bytes32 role) {\n if (!hasRole(role, address(0))) {\n _checkRole(role, _msgSender());\n }\n _;\n }\n\n /**\n * @dev Contract might receive/hold ETH as part of the maintenance process.\n */\n receive() external payable {}\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, AccessControlUpgradeable) returns (bool) {\n return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns whether an id correspond to a registered operation. This\n * includes both Pending, Ready and Done operations.\n */\n function isOperation(bytes32 id) public view virtual returns (bool) {\n return getTimestamp(id) > 0;\n }\n\n /**\n * @dev Returns whether an operation is pending or not. Note that a \"pending\" operation may also be \"ready\".\n */\n function isOperationPending(bytes32 id) public view virtual returns (bool) {\n return getTimestamp(id) > _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns whether an operation is ready for execution. Note that a \"ready\" operation is also \"pending\".\n */\n function isOperationReady(bytes32 id) public view virtual returns (bool) {\n uint256 timestamp = getTimestamp(id);\n return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;\n }\n\n /**\n * @dev Returns whether an operation is done or not.\n */\n function isOperationDone(bytes32 id) public view virtual returns (bool) {\n return getTimestamp(id) == _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Returns the timestamp at which an operation becomes ready (0 for\n * unset operations, 1 for done operations).\n */\n function getTimestamp(bytes32 id) public view virtual returns (uint256) {\n return _timestamps[id];\n }\n\n /**\n * @dev Returns the minimum delay for an operation to become valid.\n *\n * This value can be changed by executing an operation that calls `updateDelay`.\n */\n function getMinDelay() public view virtual returns (uint256) {\n return _minDelay;\n }\n\n /**\n * @dev Returns the identifier of an operation containing a single\n * transaction.\n */\n function hashOperation(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32) {\n return keccak256(abi.encode(target, value, data, predecessor, salt));\n }\n\n /**\n * @dev Returns the identifier of an operation containing a batch of\n * transactions.\n */\n function hashOperationBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public pure virtual returns (bytes32) {\n return keccak256(abi.encode(targets, values, payloads, predecessor, salt));\n }\n\n /**\n * @dev Schedule an operation containing a single transaction.\n *\n * Emits {CallSalt} if salt is nonzero, and {CallScheduled}.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function schedule(\n address target,\n uint256 value,\n bytes calldata data,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n bytes32 id = hashOperation(target, value, data, predecessor, salt);\n _schedule(id, delay);\n emit CallScheduled(id, 0, target, value, data, predecessor, delay);\n if (salt != bytes32(0)) {\n emit CallSalt(id, salt);\n }\n }\n\n /**\n * @dev Schedule an operation containing a batch of transactions.\n *\n * Emits {CallSalt} if salt is nonzero, and one {CallScheduled} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'proposer' role.\n */\n function scheduleBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt,\n uint256 delay\n ) public virtual onlyRole(PROPOSER_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n _schedule(id, delay);\n for (uint256 i = 0; i < targets.length; ++i) {\n emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);\n }\n if (salt != bytes32(0)) {\n emit CallSalt(id, salt);\n }\n }\n\n /**\n * @dev Schedule an operation that is to become valid after a given delay.\n */\n function _schedule(bytes32 id, uint256 delay) private {\n require(!isOperation(id), \"TimelockController: operation already scheduled\");\n require(delay >= getMinDelay(), \"TimelockController: insufficient delay\");\n _timestamps[id] = block.timestamp + delay;\n }\n\n /**\n * @dev Cancel an operation.\n *\n * Requirements:\n *\n * - the caller must have the 'canceller' role.\n */\n function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {\n require(isOperationPending(id), \"TimelockController: operation cannot be cancelled\");\n delete _timestamps[id];\n\n emit Cancelled(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a single transaction.\n *\n * Emits a {CallExecuted} event.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n // thus any modifications to the operation during reentrancy should be caught.\n // slither-disable-next-line reentrancy-eth\n function execute(\n address target,\n uint256 value,\n bytes calldata payload,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n bytes32 id = hashOperation(target, value, payload, predecessor, salt);\n\n _beforeCall(id, predecessor);\n _execute(target, value, payload);\n emit CallExecuted(id, 0, target, value, payload);\n _afterCall(id);\n }\n\n /**\n * @dev Execute an (ready) operation containing a batch of transactions.\n *\n * Emits one {CallExecuted} event per transaction in the batch.\n *\n * Requirements:\n *\n * - the caller must have the 'executor' role.\n */\n // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n // thus any modifications to the operation during reentrancy should be caught.\n // slither-disable-next-line reentrancy-eth\n function executeBatch(\n address[] calldata targets,\n uint256[] calldata values,\n bytes[] calldata payloads,\n bytes32 predecessor,\n bytes32 salt\n ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n require(targets.length == values.length, \"TimelockController: length mismatch\");\n require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n\n _beforeCall(id, predecessor);\n for (uint256 i = 0; i < targets.length; ++i) {\n address target = targets[i];\n uint256 value = values[i];\n bytes calldata payload = payloads[i];\n _execute(target, value, payload);\n emit CallExecuted(id, i, target, value, payload);\n }\n _afterCall(id);\n }\n\n /**\n * @dev Execute an operation's call.\n */\n function _execute(address target, uint256 value, bytes calldata data) internal virtual {\n (bool success, ) = target.call{value: value}(data);\n require(success, \"TimelockController: underlying transaction reverted\");\n }\n\n /**\n * @dev Checks before execution of an operation's calls.\n */\n function _beforeCall(bytes32 id, bytes32 predecessor) private view {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n require(predecessor == bytes32(0) || isOperationDone(predecessor), \"TimelockController: missing dependency\");\n }\n\n /**\n * @dev Checks after execution of an operation's calls.\n */\n function _afterCall(bytes32 id) private {\n require(isOperationReady(id), \"TimelockController: operation is not ready\");\n _timestamps[id] = _DONE_TIMESTAMP;\n }\n\n /**\n * @dev Changes the minimum timelock duration for future operations.\n *\n * Emits a {MinDelayChange} event.\n *\n * Requirements:\n *\n * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing\n * an operation where the timelock is the target and the data is the ABI-encoded call to this function.\n */\n function updateDelay(uint256 newDelay) external virtual {\n require(msg.sender == address(this), \"TimelockController: caller must be timelock\");\n emit MinDelayChange(_minDelay, newDelay);\n _minDelay = newDelay;\n }\n\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155Received}.\n */\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /**\n * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n */\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public virtual override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "contracts/test/mocks/GovernorCountingOverridableHarness.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol\";\n\nimport \"../../treasury/GovernorCountingOverridable.sol\";\n\n/**\n * @dev This is a concrete contract to test the GovernorCountingOverridable extension. It implements the minimum\n * necessary to get a working Governor to test the extension.\n */\ncontract GovernorCountingOverridableHarness is\n Initializable,\n GovernorUpgradeable,\n GovernorSettingsUpgradeable,\n GovernorVotesUpgradeable,\n GovernorCountingOverridable\n{\n // use non-standard values for these to test if it's really used\n uint256 constant QUOTA = 420000; // 42%\n uint256 constant QUORUM = 370000; // 37%\n\n IVotes internal iVotes; // 🍎\n\n function initialize(IVotes _votes) public initializer {\n iVotes = _votes;\n\n __Governor_init(\"GovernorCountingOverridableConcrete\");\n __GovernorSettings_init(\n 0, /* no voting delay */\n 100, /* 100 blocks voting period */\n 0 /* no minimum proposal threshold */\n );\n\n __GovernorVotes_init(iVotes);\n __GovernorCountingOverridable_init(QUOTA);\n }\n\n function votes() public view override returns (IVotes) {\n return iVotes;\n }\n\n function quorum(uint256 timepoint) public view virtual override returns (uint256) {\n uint256 totalSupply = iVotes.getPastTotalSupply(timepoint);\n return MathUtils.percOf(totalSupply, QUORUM);\n }\n\n /**\n * @dev Expose internal _quorumReached function for testing.\n */\n function quorumReached(uint256 proposalId) public view returns (bool) {\n return super._quorumReached(proposalId);\n }\n\n /**\n * @dev Expose internal _voteSucceeded function for testing.\n */\n function voteSucceeded(uint256 proposalId) public view returns (bool) {\n return super._voteSucceeded(proposalId);\n }\n\n function proposalThreshold()\n public\n view\n override(GovernorUpgradeable, GovernorSettingsUpgradeable)\n returns (uint256)\n {\n return super.proposalThreshold();\n }\n}\n" + }, + "contracts/bonding/BondingVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/Arrays.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport \"./libraries/EarningsPool.sol\";\nimport \"./libraries/EarningsPoolLIP36.sol\";\nimport \"./libraries/SortedArrays.sol\";\n\nimport \"../ManagerProxyTarget.sol\";\nimport \"./IBondingVotes.sol\";\nimport \"./IBondingManager.sol\";\nimport \"../rounds/IRoundsManager.sol\";\n\n/**\n * @title BondingVotes\n * @dev Checkpointing logic for BondingManager state for historical stake calculations.\n */\ncontract BondingVotes is ManagerProxyTarget, IBondingVotes {\n using Arrays for uint256[];\n using SortedArrays for uint256[];\n\n struct BondingCheckpoint {\n /**\n * @dev The amount of bonded tokens to another delegate as of the lastClaimRound.\n */\n uint256 bondedAmount;\n /**\n * @dev The address of the delegate the account is bonded to. In case of transcoders this is their own address.\n */\n address delegateAddress;\n /**\n * @dev The amount of tokens delegated from delegators to this account. This is only set for transcoders, which\n * have to self-delegate first and then have tokens bonded from other delegators.\n */\n uint256 delegatedAmount;\n /**\n * @dev The last round during which the delegator claimed its earnings. This pegs the value of bondedAmount for\n * rewards calculation in {EarningsPoolLIP36-delegatorCumulativeStakeAndFees}.\n */\n uint256 lastClaimRound;\n /**\n * @dev The last round during which the checkpointed account called {BondingManager-reward}. This is needed to\n * when calculating pending rewards for a delegator to this transcoder, to find the last earning pool available\n * for a given round. In that case we start from the delegator checkpoint and then fetch its delegate address\n * checkpoint as well to find the last earning pool.\n *\n * Notice that this is the only field that comes from the Transcoder struct in BondingManager, not Delegator.\n */\n uint256 lastRewardRound;\n }\n\n /**\n * @dev Stores a list of checkpoints for an account, queryable and mapped by start round. To access the checkpoint\n * for a given round, find the checkpoint with the highest start round that is lower or equal to the queried round\n * ({SortedArrays-findLowerBound}) and then fetch the specific checkpoint on the data mapping.\n */\n struct BondingCheckpointsByRound {\n uint256[] startRounds;\n mapping(uint256 => BondingCheckpoint) data;\n }\n\n /**\n * @dev Stores a list of checkpoints for the total active stake, queryable and mapped by round. Notice that\n * differently from bonding checkpoints, it's only accessible on the specific round. To access the checkpoint for a\n * given round, look for the checkpoint in the {data}} and if it's zero ensure the round was actually checkpointed on\n * the {rounds} array ({SortedArrays-findLowerBound}).\n */\n struct TotalActiveStakeByRound {\n uint256[] rounds;\n mapping(uint256 => uint256) data;\n }\n\n /**\n * @dev Checkpoints by account (delegators and transcoders).\n */\n mapping(address => BondingCheckpointsByRound) private bondingCheckpoints;\n /**\n * @dev Total active stake checkpoints.\n */\n TotalActiveStakeByRound private totalStakeCheckpoints;\n\n /**\n * @dev Modifier to ensure the sender is BondingManager\n */\n modifier onlyBondingManager() {\n _onlyBondingManager();\n _;\n }\n\n /**\n * @dev Ensures that the provided round is in the past.\n */\n modifier onlyPastRounds(uint256 _round) {\n uint256 currentRound = clock();\n if (_round >= currentRound) {\n revert FutureLookup(_round, currentRound == 0 ? 0 : currentRound - 1);\n }\n _;\n }\n\n /**\n * @notice BondingVotes constructor. Only invokes constructor of base Manager contract with provided Controller address\n * @param _controller Address of Controller that this contract will be registered with\n */\n constructor(address _controller) Manager(_controller) {}\n\n // IVotes interface implementation.\n // These should not access any storage directly but proxy to the historical stake functions below.\n\n /**\n * @notice Returns the name of the virtual token implemented by this.\n */\n function name() external pure returns (string memory) {\n return \"Livepeer Voting Power\";\n }\n\n /**\n * @notice Returns the symbol of the token underlying the voting power.\n */\n function symbol() external pure returns (string memory) {\n return \"vLPT\";\n }\n\n /**\n * @notice Returns the decimals places of the token underlying the voting.\n */\n function decimals() external pure returns (uint8) {\n return 18;\n }\n\n /**\n * @notice Clock is set to match the current round, which is the checkpointing\n * method implemented here.\n */\n function clock() public view returns (uint48) {\n return SafeCast.toUint48(roundsManager().currentRound());\n }\n\n /**\n * @notice Machine-readable description of the clock as specified in EIP-6372.\n */\n // solhint-disable-next-line func-name-mixedcase\n function CLOCK_MODE() external pure returns (string memory) {\n return \"mode=livepeer_round\";\n }\n\n /**\n * @notice Returns the current amount of votes that `_account` has.\n *\n * The voting power for a delegator is the amount they are delegating to a transcoder, while for transcoders it is\n * all the stake delegated to them. If an account is not a registered transcoder\n * ({BondingManager-isRegisteredTranscoder}), the voting power of itself and of all its delegators will be zero.\n */\n function getVotes(address _account) external view returns (uint256) {\n (uint256 votes, ) = getVotesAndDelegateAtRoundStart(_account, clock() + 1);\n return votes;\n }\n\n /**\n * @notice Returns the amount of votes that `_account` had at the end of the provided past `_round`.\n */\n function getPastVotes(address _account, uint256 _round) external view onlyPastRounds(_round) returns (uint256) {\n (uint256 votes, ) = getVotesAndDelegateAtRoundStart(_account, _round + 1);\n return votes;\n }\n\n /**\n * @notice Returns the current total supply of votes available.\n * @dev This value is the sum of all *active* stake, which is not necessarily the sum of all voting power.\n * Bonded stake that is not part of the top 100 active transcoder set is still given voting power, but is not\n * considered here.\n */\n function totalSupply() external view returns (uint256) {\n return getTotalActiveStakeAt(clock() + 1);\n }\n\n /**\n * @notice Returns the total supply of votes available at the end of the provided past `_round`.\n * @dev This value is the sum of all *active* stake, which is not necessarily the sum of all voting power.\n * Bonded stake that is not part of the top 100 active transcoder set is still given voting power, but is not\n * considered here.\n */\n function getPastTotalSupply(uint256 _round) external view onlyPastRounds(_round) returns (uint256) {\n return getTotalActiveStakeAt(_round + 1);\n }\n\n /**\n * @notice Returns the delegate that _account has chosen. This means the delegated transcoder address in case of\n * delegators, and the account's own address for transcoders (self-delegated).\n */\n function delegates(address _account) external view returns (address) {\n (, address delegateAddress) = getVotesAndDelegateAtRoundStart(_account, clock() + 1);\n return delegateAddress;\n }\n\n /**\n * @notice Returns the delegate that _account had chosen at the end of the provided past `_round`.\n * @dev This is an addition to the IERC5805 interface to support our custom vote counting logic that allows\n * delegators to override their transcoders votes. See {GovernorCountingOverridable-_handleVoteOverrides}.\n */\n function delegatedAt(address _account, uint256 _round) external view onlyPastRounds(_round) returns (address) {\n (, address delegateAddress) = getVotesAndDelegateAtRoundStart(_account, _round + 1);\n return delegateAddress;\n }\n\n /**\n * @notice Delegation through BondingVotes is not supported.\n */\n function delegate(address) external pure {\n revert MustCallBondingManager(\"bond\");\n }\n\n /**\n * @notice Delegation through BondingVotes is not supported.\n */\n function delegateBySig(\n address,\n uint256,\n uint256,\n uint8,\n bytes32,\n bytes32\n ) external pure {\n revert MustCallBondingManager(\"bondFor\");\n }\n\n // BondingManager checkpointing hooks\n\n /**\n * @notice Called by the BondingManager when the bonding state of an account changes.\n * @dev Since we checkpoint \"delegator\" and \"transcoder\" states, this is called both for the delegator and for the\n * transcoder when any change is made to the bonds, including when rewards are calculated or claimed.\n * @param _account The account whose bonding state changed\n * @param _startRound The round from which the bonding state will be active. This is normally the next round.\n * @param _bondedAmount From {BondingManager-Delegator-bondedAmount}\n * @param _delegateAddress From {BondingManager-Delegator-delegateAddress}\n * @param _delegatedAmount From {BondingManager-Transcoder-delegatedAmount}\n * @param _lastClaimRound From {BondingManager-Delegator-lastClaimRound}\n * @param _lastRewardRound From {BondingManager-Transcoder-lastRewardRound}\n */\n function checkpointBondingState(\n address _account,\n uint256 _startRound,\n uint256 _bondedAmount,\n address _delegateAddress,\n uint256 _delegatedAmount,\n uint256 _lastClaimRound,\n uint256 _lastRewardRound\n ) external virtual onlyBondingManager {\n if (_startRound != clock() + 1) {\n revert InvalidStartRound(_startRound, clock() + 1);\n } else if (_lastClaimRound >= _startRound) {\n revert FutureLastClaimRound(_lastClaimRound, _startRound - 1);\n }\n\n BondingCheckpoint memory previous;\n if (hasCheckpoint(_account)) {\n previous = getBondingCheckpointAt(_account, _startRound);\n }\n\n BondingCheckpointsByRound storage checkpoints = bondingCheckpoints[_account];\n\n BondingCheckpoint memory bond = BondingCheckpoint({\n bondedAmount: _bondedAmount,\n delegateAddress: _delegateAddress,\n delegatedAmount: _delegatedAmount,\n lastClaimRound: _lastClaimRound,\n lastRewardRound: _lastRewardRound\n });\n checkpoints.data[_startRound] = bond;\n\n // now store the startRound itself in the startRounds array to allow us\n // to find it and lookup in the above mapping\n checkpoints.startRounds.pushSorted(_startRound);\n\n onBondingCheckpointChanged(_account, previous, bond);\n }\n\n /**\n * @notice Called by the BondingManager when the total active stake changes.\n * @dev This is called only from the {BondingManager-setCurrentRoundTotalActiveStake} function to set the total\n * active stake in the current round.\n * @param _totalStake From {BondingManager-currentRoundTotalActiveStake}\n * @param _round The round for which the total active stake is valid. This is normally the current round.\n */\n function checkpointTotalActiveStake(uint256 _totalStake, uint256 _round) external virtual onlyBondingManager {\n if (_round != clock()) {\n revert InvalidTotalStakeCheckpointRound(_round, clock());\n }\n\n totalStakeCheckpoints.data[_round] = _totalStake;\n totalStakeCheckpoints.rounds.pushSorted(_round);\n }\n\n /**\n * @notice Returns whether an account already has any checkpoint.\n */\n function hasCheckpoint(address _account) public view returns (bool) {\n return bondingCheckpoints[_account].startRounds.length > 0;\n }\n\n // Historical stake access functions\n\n /**\n * @notice Get the total active stake at the start of a given round.\n *\n * Notice that this function is different from the {IERC5805Upgradeable} functions above that return the state at\n * the *end* of the round. The state at the end of a round is equal to the state at the start of the next round, so\n * to get the same result here, call this function with `round+1` instead.\n * @param _round The round for which we want to get the total active stake.\n */\n function getTotalActiveStakeAt(uint256 _round) public view virtual returns (uint256) {\n if (_round > clock() + 1) {\n revert FutureLookup(_round, clock() + 1);\n }\n\n uint256 exactCheckpoint = totalStakeCheckpoints.data[_round];\n if (exactCheckpoint > 0) {\n return exactCheckpoint;\n }\n\n uint256[] storage initializedRounds = totalStakeCheckpoints.rounds;\n uint256 upper = initializedRounds.findUpperBound(_round);\n if (upper == 0) {\n // Return a zero voting power supply for any round before the first checkpoint. This also happens if there\n // are no checkpoints at all.\n return 0;\n } else if (upper < initializedRounds.length) {\n // Use the checkpoint from the next initialized round, which got the next total active stake checkpointed.\n uint256 nextInitedRound = initializedRounds[upper];\n return totalStakeCheckpoints.data[nextInitedRound];\n } else {\n // Here the _round is after any initialized round, so grab its stake from nextRoundTotalActiveStake()\n return bondingManager().nextRoundTotalActiveStake();\n }\n }\n\n /**\n * @notice Gets the voting power and delegate of an account at the start of a given round.\n *\n * Notice that this function is different from the {IERC5805Upgradeable} functions above that return the state at\n * the *end* of the round. The state at the end of a round is equal to the state at the start of the next round, so\n * to get the same result here, call this function with `round+1` instead.\n * @dev The value returned by this can also be calculated with the following logic using BondingManager functions at\n * the start of the corresponding round:\n * - If `isRegisteredTranscoder(_account)`, the result is `(transcoderTotalStake(_account), _account)`\n * - Otherwise, the `delegate` is obtained from `getDelegator(_account).delegateAddress`\n * - If `isRegisteredTranscoder(delegate)`, the result is `(pendingStake(_account, 0), delegate)`\n * - Otherwise, the result is `(0, delegate)`\n * @param _account The account to get the voting power and delegate from.\n * @param _round The round at which to get the account state (at round start).\n * @return votes The voting power of the account at the start of the given round.\n * @return delegateAddress The address the account delegated to at the start of the given round.\n */\n function getVotesAndDelegateAtRoundStart(address _account, uint256 _round)\n public\n view\n virtual\n returns (uint256 votes, address delegateAddress)\n {\n BondingCheckpoint storage bond = getBondingCheckpointAt(_account, _round);\n\n delegateAddress = bond.delegateAddress;\n\n if (bond.bondedAmount == 0) {\n votes = 0;\n } else if (isRegisteredTranscoder(_account, bond)) {\n // Address is a registered transcoder so we use its delegated amount. This includes self and delegated stake\n // as well as any accrued rewards, even unclaimed ones\n votes = bond.delegatedAmount;\n } else {\n // Address is NOT a registered transcoder so we calculate its cumulative stake for the voting power\n votes = delegatorVotesAtRoundStart(bond, _round);\n }\n }\n\n /**\n * @dev Reacts to changes in the bonding checkpoints of an account by emitting the corresponding events.\n */\n function onBondingCheckpointChanged(\n address _account,\n BondingCheckpoint memory previous,\n BondingCheckpoint memory current\n ) internal {\n address previousDelegate = previous.delegateAddress;\n address newDelegate = current.delegateAddress;\n if (previousDelegate != newDelegate) {\n emit DelegateChanged(_account, previousDelegate, newDelegate);\n }\n\n // same logic as {isRegisteredTranscoder} with the memory BondingCheckpoints\n bool isTranscoder = newDelegate == _account && current.bondedAmount > 0;\n bool wasTranscoder = previousDelegate == _account && previous.bondedAmount > 0;\n // we want to register zero \"delegate votes\" when the account is/was not a transcoder\n uint256 previousDelegateVotes = wasTranscoder ? previous.delegatedAmount : 0;\n uint256 currentDelegateVotes = isTranscoder ? current.delegatedAmount : 0;\n if (previousDelegateVotes != currentDelegateVotes) {\n emit DelegateVotesChanged(_account, previousDelegateVotes, currentDelegateVotes);\n }\n\n // Always send delegator events since transcoders are delegators themselves. The way our rewards work, the\n // delegator voting power calculated from events will only reflect their claimed stake without pending rewards.\n if (previous.bondedAmount != current.bondedAmount || previous.lastClaimRound != current.lastClaimRound) {\n emit DelegatorBondedAmountChanged(\n _account,\n previous.bondedAmount,\n previous.lastClaimRound,\n current.bondedAmount,\n current.lastClaimRound\n );\n }\n }\n\n /**\n * @dev Gets the checkpointed bonding state of an account at a round. This works by looking for the last checkpoint\n * at or before the given round and using the checkpoint of that round. If there hasn't been checkpoints since then\n * it means that the state hasn't changed.\n * @param _account The account whose bonding state we want to get.\n * @param _round The round for which we want to get the bonding state.\n * @return The {BondingCheckpoint} pointer to the checkpoints storage.\n */\n function getBondingCheckpointAt(address _account, uint256 _round)\n internal\n view\n returns (BondingCheckpoint storage)\n {\n if (_round > clock() + 1) {\n revert FutureLookup(_round, clock() + 1);\n }\n\n BondingCheckpointsByRound storage checkpoints = bondingCheckpoints[_account];\n\n // Most of the time we will be calling this for a transcoder which checkpoints on every round through reward().\n // On those cases we will have a checkpoint for exactly the round we want, so optimize for that.\n BondingCheckpoint storage bond = checkpoints.data[_round];\n if (bond.bondedAmount > 0) {\n return bond;\n }\n\n uint256 startRoundIdx = checkpoints.startRounds.findLowerBound(_round);\n if (startRoundIdx == checkpoints.startRounds.length) {\n // No checkpoint at or before _round, so return the zero BondingCheckpoint value. This also happens if there\n // are no checkpoints for _account. The voting power will be zero until the first checkpoint is made.\n return bond;\n }\n\n uint256 startRound = checkpoints.startRounds[startRoundIdx];\n return checkpoints.data[startRound];\n }\n\n /**\n * @dev Gets the voting power of a delegator at the start of the given round. This is done through cumulative\n * rewards calculation on top of the bonding state.\n *\n * Differently from the bonding manager implementation, we can calculate the stake at any round through the use of\n * the checkpointed state. It works by re-using the bonding manager logic while changing only the way that we find\n * the earning pool for the end round.\n * @param bond The {BondingCheckpoint} of the delegator at the given round.\n * @param _round The round at which we want the delegator votes (at round start).\n * @return The cumulative stake of the delegator at the start of the given round.\n */\n function delegatorVotesAtRoundStart(BondingCheckpoint storage bond, uint256 _round)\n internal\n view\n returns (uint256)\n {\n address transcoder = bond.delegateAddress;\n EarningsPool.Data memory startPool = getTranscoderEarningsPoolForRound(transcoder, bond.lastClaimRound);\n\n (\n BondingCheckpoint storage transcoderBond,\n EarningsPool.Data memory endPool\n ) = getLastTranscoderRewardsEarningsPool(transcoder, _round);\n\n if (!isRegisteredTranscoder(transcoder, transcoderBond)) {\n // Delegating to an account that is not actually a transcoder should render no voting power.\n return 0;\n }\n\n if (transcoderBond.lastRewardRound < bond.lastClaimRound) {\n // If the transcoder hasn't called reward() since the last time the delegator claimed earnings, there will\n // be no rewards to add to the delegator's stake so we just return the originally bonded amount.\n return bond.bondedAmount;\n }\n\n return EarningsPoolLIP36.delegatorCumulativeStake(startPool, endPool, bond.bondedAmount);\n }\n\n /**\n * @notice Returns the last initialized earning pool for a transcoder at a given round.\n * @dev Transcoders are just delegators with a self-delegation, so we find their last checkpoint before or at the\n * provided _round and use its lastRewardRound value to grab the calculated earning pool. The only case where this\n * returns a zero earning pool is if the transcoder had never called reward() before _round.\n * @param _transcoder Address of the transcoder to look for\n * @param _round Past round at which we want the valid earning pool from\n * @return bond The BondingCheckpoint from the transcoder at the given _round.\n * @return pool EarningsPool.Data struct with the last initialized earning pool.\n */\n function getLastTranscoderRewardsEarningsPool(address _transcoder, uint256 _round)\n internal\n view\n returns (BondingCheckpoint storage bond, EarningsPool.Data memory pool)\n {\n bond = getBondingCheckpointAt(_transcoder, _round);\n\n uint256 rewardRound = bond.lastRewardRound;\n if (rewardRound > 0) {\n pool = getTranscoderEarningsPoolForRound(_transcoder, rewardRound);\n\n if (pool.cumulativeRewardFactor == 0) {\n // Invalid state: a lastRewardRound is registered but there's no recorded earnings pool.\n revert MissingEarningsPool(_transcoder, rewardRound);\n }\n }\n }\n\n /**\n * @dev Proxy for {BondingManager-getTranscoderEarningsPoolForRound} that returns an EarningsPool.Data struct.\n */\n function getTranscoderEarningsPoolForRound(address _transcoder, uint256 _round)\n internal\n view\n returns (EarningsPool.Data memory pool)\n {\n (\n pool.totalStake,\n pool.transcoderRewardCut,\n pool.transcoderFeeShare,\n pool.cumulativeRewardFactor,\n pool.cumulativeFeeFactor\n ) = bondingManager().getTranscoderEarningsPoolForRound(_transcoder, _round);\n }\n\n /**\n * @dev Returns whether an account should be considered a transcoder at the given checkpoint. The logic matches what\n * is in {BondingManager-isRegisteredTranscoder}.\n */\n function isRegisteredTranscoder(address _account, BondingCheckpoint storage _bond) internal view returns (bool) {\n return _bond.delegateAddress == _account && _bond.bondedAmount > 0;\n }\n\n // Manager/Controller helpers\n\n /**\n * @dev Return BondingManager interface\n */\n function bondingManager() internal view returns (IBondingManager) {\n return IBondingManager(controller.getContract(keccak256(\"BondingManager\")));\n }\n\n /**\n * @dev Return IRoundsManager interface\n */\n function roundsManager() internal view returns (IRoundsManager) {\n return IRoundsManager(controller.getContract(keccak256(\"RoundsManager\")));\n }\n\n /**\n * @dev Ensure the sender is BondingManager\n */\n function _onlyBondingManager() internal view {\n if (msg.sender != address(bondingManager())) {\n revert InvalidCaller(msg.sender, address(bondingManager()));\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "contracts/test/mocks/BondingVotesERC5805Harness.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../bonding/BondingVotes.sol\";\nimport \"./GenericMock.sol\";\n\n/**\n * @dev This is a tets utility for unit tests on the ERC5805 functions of the BondingVotes contract. It overrides the\n * functions that should be used to derive the values returned by the ERC5805 functions and checks against those.\n */\ncontract BondingVotesERC5805Harness is BondingVotes {\n constructor(address _controller) BondingVotes(_controller) {}\n\n /**\n * @dev Mocked version that returns transformed version of the input for testing.\n * @return amount lowest 4 bytes of address + _round\n * @return delegateAddress (_account << 4) | _round.\n */\n function getVotesAndDelegateAtRoundStart(address _account, uint256 _round)\n public\n pure\n override\n returns (uint256 amount, address delegateAddress)\n {\n uint160 intAddr = uint160(_account);\n\n amount = (intAddr & 0xffffffff) + _round;\n delegateAddress = address((intAddr << 4) | uint160(_round));\n }\n\n function getTotalActiveStakeAt(uint256 _round) public pure override returns (uint256) {\n return 4 * _round;\n }\n}\n" + }, + "contracts/test/mocks/GenericMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\n/**\n * @title A mock contract that can set/return mock values and execute functions\n * on target contracts\n */\ncontract GenericMock {\n struct MockValue {\n uint256 uint256Value;\n bytes32 bytes32Value;\n bool boolValue;\n address addressValue;\n MockValueType valueType;\n bool set;\n mapping(bytes32 => uint256) uint256Values;\n }\n\n enum MockValueType {\n Uint256,\n Bytes32,\n Bool,\n Address\n }\n\n // Track function selectors and mapped mock values\n mapping(bytes4 => MockValue) mockValues;\n\n /**\n * @dev Return mock value for a functione\n */\n fallback() external payable {\n bytes4 func;\n assembly {\n func := calldataload(0)\n }\n\n bytes32 dataHash = keccak256(abi.encodePacked(msg.data));\n\n if (!mockValues[func].set) {\n // If mock value not set, default to return a bool with value false\n mLoadAndReturn(false);\n } else {\n if (mockValues[func].valueType == MockValueType.Uint256) {\n uint256 value = mockValues[func].uint256Values[dataHash];\n // TODO: Make sure we don't go into this code block if the value set\n // for dataHash should actually be 0\n if (value == 0) {\n value = mockValues[func].uint256Value;\n }\n mLoadAndReturn(value);\n } else if (mockValues[func].valueType == MockValueType.Bytes32) {\n mLoadAndReturn(mockValues[func].bytes32Value);\n } else if (mockValues[func].valueType == MockValueType.Bool) {\n mLoadAndReturn(mockValues[func].boolValue);\n } else if (mockValues[func].valueType == MockValueType.Address) {\n mLoadAndReturn(mockValues[func].addressValue);\n }\n }\n }\n\n /**\n * @dev Empty receive function as dummy impl to supress compiler warnings.\n */\n receive() external payable {}\n\n /**\n * @dev Call a function on a target address using provided calldata for a function\n * @param _target Target contract to call with data\n * @param _data Transaction data to be used to call the target contract\n */\n function execute(address _target, bytes calldata _data) external payable {\n // solium-disable-next-line\n (bool ok, bytes memory res) = _target.call{ value: msg.value }(_data);\n require(ok, string(res));\n }\n\n /**\n * @dev Set a mock uint256 value for a function\n * @param _func Function selector (bytes4(keccak256(FUNCTION_SIGNATURE)))\n * @param _value Mock uint256 value\n */\n function setMockUint256(bytes4 _func, uint256 _value) external {\n mockValues[_func].valueType = MockValueType.Uint256;\n mockValues[_func].uint256Value = _value;\n mockValues[_func].set = true;\n }\n\n /**\n * @dev Set a mockuint256 value for a function with specific params passed\n * @param _func Function selector (bytes4(keccak256(FUNCTION_SIGNATURE)))\n * @param _dataHash keccak256 hash of tx data i.e. keccak256(msg.data)\n * @param _value Mock uint256 value\n */\n function setMockUint256WithParam(\n bytes4 _func,\n bytes32 _dataHash,\n uint256 _value\n ) external {\n mockValues[_func].valueType = MockValueType.Uint256;\n mockValues[_func].uint256Values[_dataHash] = _value;\n mockValues[_func].set = true;\n }\n\n /**\n * @dev Set a mock bytes32 value for a function\n * @param _func Function selector (bytes4(keccak256(FUNCTION_SIGNATURE)))\n * param _value Mock bytes32 value\n */\n function setMockBytes32(bytes4 _func, bytes32 _value) external {\n mockValues[_func].valueType = MockValueType.Bytes32;\n mockValues[_func].bytes32Value = _value;\n mockValues[_func].set = true;\n }\n\n /**\n * @dev Set a mock bool value for a function\n * @param _func Function selector (bytes4(keccak256(FUNCTION_SIGNATURE)))\n * @param _value Mock bool value\n */\n function setMockBool(bytes4 _func, bool _value) external {\n mockValues[_func].valueType = MockValueType.Bool;\n mockValues[_func].boolValue = _value;\n mockValues[_func].set = true;\n }\n\n /**\n * @dev Set a mock address value for a function\n * @param _func Function selector (bytes4(keccak256(FUNCTION_SIGNATURE)))\n * @param _value Mock address value\n */\n function setMockAddress(bytes4 _func, address _value) external {\n mockValues[_func].valueType = MockValueType.Address;\n mockValues[_func].addressValue = _value;\n mockValues[_func].set = true;\n }\n\n /**\n * @dev Load a uint256 value into memory and return it\n * @param _value Uint256 value\n */\n function mLoadAndReturn(uint256 _value) private pure {\n assembly {\n let memOffset := mload(0x40)\n mstore(0x40, add(memOffset, 32))\n mstore(memOffset, _value)\n return(memOffset, 32)\n }\n }\n\n /**\n * @dev Load a bytes32 value into memory and return it\n * @param _value Bytes32 value\n */\n function mLoadAndReturn(bytes32 _value) private pure {\n assembly {\n let memOffset := mload(0x40)\n mstore(0x40, add(memOffset, 32))\n mstore(memOffset, _value)\n return(memOffset, 32)\n }\n }\n\n /**\n * @dev Load a bool value into memory and return it\n * @param _value Bool value\n */\n function mLoadAndReturn(bool _value) private pure {\n assembly {\n let memOffset := mload(0x40)\n mstore(0x40, add(memOffset, 32))\n mstore(memOffset, _value)\n return(memOffset, 32)\n }\n }\n\n /**\n * @dev Load an address value into memory and return it\n * @param _value Address value\n */\n function mLoadAndReturn(address _value) private pure {\n assembly {\n let memOffset := mload(0x40)\n mstore(0x40, add(memOffset, 32))\n mstore(memOffset, _value)\n return(memOffset, 32)\n }\n }\n}\n" + }, + "contracts/test/mocks/MinterMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./GenericMock.sol\";\n\ncontract MinterMock is GenericMock {\n event TrustedWithdrawETH(address to, uint256 amount);\n event TrustedTransferTokens(address to, uint256 amount);\n\n function trustedWithdrawETH(address _to, uint256 _amount) external {\n emit TrustedWithdrawETH(_to, _amount);\n }\n\n function trustedTransferTokens(address _to, uint256 _amount) external {\n emit TrustedTransferTokens(_to, _amount);\n }\n}\n" + }, + "contracts/test/mocks/BondingVotesMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./GenericMock.sol\";\n\ncontract BondingVotesMock is GenericMock {\n event CheckpointBondingState(\n address account,\n uint256 startRound,\n uint256 bondedAmount,\n address delegateAddress,\n uint256 delegatedAmount,\n uint256 lastClaimRound,\n uint256 lastRewardRound\n );\n event CheckpointTotalActiveStake(uint256 totalStake, uint256 round);\n\n function checkpointBondingState(\n address _account,\n uint256 _startRound,\n uint256 _bondedAmount,\n address _delegateAddress,\n uint256 _delegatedAmount,\n uint256 _lastClaimRound,\n uint256 _lastRewardRound\n ) external {\n emit CheckpointBondingState(\n _account,\n _startRound,\n _bondedAmount,\n _delegateAddress,\n _delegatedAmount,\n _lastClaimRound,\n _lastRewardRound\n );\n }\n\n function checkpointTotalActiveStake(uint256 _totalStake, uint256 _round) external {\n emit CheckpointTotalActiveStake(_totalStake, _round);\n }\n}\n" + }, + "contracts/test/mocks/BondingManagerMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./GenericMock.sol\";\n\ncontract BondingManagerMock is GenericMock {\n event UpdateTranscoderWithFees(address transcoder, uint256 fees, uint256 round);\n\n struct EarningsPoolMock {\n uint256 totalStake;\n uint256 transcoderRewardCut;\n uint256 transcoderFeeShare;\n uint256 cumulativeRewardFactor;\n uint256 cumulativeFeeFactor;\n }\n\n struct DelegatorMock {\n uint256 bondedAmount;\n uint256 fees;\n address delegateAddress;\n uint256 delegatedAmount;\n uint256 startRound;\n uint256 lastClaimRound;\n uint256 nextUnbondingLockId;\n }\n\n mapping(address => mapping(uint256 => EarningsPoolMock)) private earningPoolMocks;\n\n mapping(address => DelegatorMock) private delegatorMocks;\n\n function updateTranscoderWithFees(\n address _transcoder,\n uint256 _fees,\n uint256 _round\n ) external {\n emit UpdateTranscoderWithFees(_transcoder, _fees, _round);\n }\n\n function getTranscoderEarningsPoolForRound(address _transcoder, uint256 _round)\n public\n view\n returns (\n uint256 totalStake,\n uint256 transcoderRewardCut,\n uint256 transcoderFeeShare,\n uint256 cumulativeRewardFactor,\n uint256 cumulativeFeeFactor\n )\n {\n EarningsPoolMock storage pool = earningPoolMocks[_transcoder][_round];\n\n totalStake = pool.totalStake;\n transcoderRewardCut = pool.transcoderRewardCut;\n transcoderFeeShare = pool.transcoderFeeShare;\n cumulativeRewardFactor = pool.cumulativeRewardFactor;\n cumulativeFeeFactor = pool.cumulativeFeeFactor;\n }\n\n function setMockTranscoderEarningsPoolForRound(\n address _transcoder,\n uint256 _round,\n uint256 _totalStake,\n uint256 _transcoderRewardCut,\n uint256 _transcoderFeeShare,\n uint256 _cumulativeRewardFactor,\n uint256 _cumulativeFeeFactor\n ) external {\n earningPoolMocks[_transcoder][_round] = EarningsPoolMock({\n totalStake: _totalStake,\n transcoderRewardCut: _transcoderRewardCut,\n transcoderFeeShare: _transcoderFeeShare,\n cumulativeRewardFactor: _cumulativeRewardFactor,\n cumulativeFeeFactor: _cumulativeFeeFactor\n });\n }\n\n function setMockDelegator(\n address _delegator,\n uint256 _bondedAmount,\n uint256 _fees,\n address _delegateAddress,\n uint256 _delegatedAmount,\n uint256 _startRound,\n uint256 _lastClaimRound,\n uint256 _nextUnbondingLockId\n ) external {\n delegatorMocks[_delegator] = DelegatorMock({\n bondedAmount: _bondedAmount,\n fees: _fees,\n delegateAddress: _delegateAddress,\n delegatedAmount: _delegatedAmount,\n startRound: _startRound,\n lastClaimRound: _lastClaimRound,\n nextUnbondingLockId: _nextUnbondingLockId\n });\n }\n\n function getDelegator(address _delegator)\n public\n view\n returns (\n uint256 bondedAmount,\n uint256 fees,\n address delegateAddress,\n uint256 delegatedAmount,\n uint256 startRound,\n uint256 lastClaimRound,\n uint256 nextUnbondingLockId\n )\n {\n DelegatorMock storage del = delegatorMocks[_delegator];\n\n bondedAmount = del.bondedAmount;\n fees = del.fees;\n delegateAddress = del.delegateAddress;\n delegatedAmount = del.delegatedAmount;\n startRound = del.startRound;\n lastClaimRound = del.lastClaimRound;\n nextUnbondingLockId = del.nextUnbondingLockId;\n }\n}\n" + }, + "contracts/rounds/RoundsManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../ManagerProxyTarget.sol\";\nimport \"./IRoundsManager.sol\";\nimport \"../bonding/IBondingManager.sol\";\nimport \"../token/IMinter.sol\";\nimport \"../libraries/MathUtils.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n/**\n * @title RoundsManager\n * @notice Manages round progression and other blockchain time related operations of the Livepeer protocol\n */\ncontract RoundsManager is ManagerProxyTarget, IRoundsManager {\n using SafeMath for uint256;\n\n // Round length in blocks\n uint256 public roundLength;\n // Lock period of a round as a % of round length\n // Transcoders cannot join the transcoder pool or change their rates during the lock period at the end of a round\n // The lock period provides delegators time to review transcoder information without changes\n // # of blocks in the lock period = (roundLength * roundLockAmount) / PERC_DIVISOR\n uint256 public roundLockAmount;\n // Last initialized round. After first round, this is the last round during which initializeRound() was called\n uint256 public lastInitializedRound;\n // Round in which roundLength was last updated\n uint256 public lastRoundLengthUpdateRound;\n // Start block of the round in which roundLength was last updated\n uint256 public lastRoundLengthUpdateStartBlock;\n\n // Mapping round number => block hash for the round\n mapping(uint256 => bytes32) internal _blockHashForRound;\n\n // LIP Upgrade Rounds\n // These can be used in conditionals to ensure backwards compatibility or skip such backwards compatibility logic\n // in case 'currentRound' > LIP-X upgrade round\n mapping(uint256 => uint256) public lipUpgradeRound; // mapping (LIP-number > round number)\n\n /**\n * @notice RoundsManager constructor. Only invokes constructor of base Manager contract with provided Controller address\n * @dev This constructor will not initialize any state variables besides `controller`. The following setter functions\n * should be used to initialize state variables post-deployment:\n * - setRoundLength()\n * - setRoundLockAmount()\n * @param _controller Address of Controller that this contract will be registered with\n */\n constructor(address _controller) Manager(_controller) {}\n\n /**\n * @notice Set round length. Only callable by the controller owner\n * @param _roundLength Round length in blocks\n */\n function setRoundLength(uint256 _roundLength) external onlyControllerOwner {\n require(_roundLength > 0, \"round length cannot be 0\");\n\n if (roundLength == 0) {\n // If first time initializing roundLength, set roundLength before\n // lastRoundLengthUpdateRound and lastRoundLengthUpdateStartBlock\n roundLength = _roundLength;\n lastRoundLengthUpdateRound = currentRound();\n lastRoundLengthUpdateStartBlock = currentRoundStartBlock();\n } else {\n // If updating roundLength, set roundLength after\n // lastRoundLengthUpdateRound and lastRoundLengthUpdateStartBlock\n lastRoundLengthUpdateRound = currentRound();\n lastRoundLengthUpdateStartBlock = currentRoundStartBlock();\n roundLength = _roundLength;\n }\n\n emit ParameterUpdate(\"roundLength\");\n }\n\n /**\n * @notice Set round lock amount. Only callable by the controller owner\n * @param _roundLockAmount Round lock amount as a % of the number of blocks in a round\n */\n function setRoundLockAmount(uint256 _roundLockAmount) external onlyControllerOwner {\n require(MathUtils.validPerc(_roundLockAmount), \"round lock amount must be a valid percentage\");\n\n roundLockAmount = _roundLockAmount;\n\n emit ParameterUpdate(\"roundLockAmount\");\n }\n\n /**\n * @notice Initialize the current round. Called once at the start of any round\n */\n function initializeRound() external whenSystemNotPaused {\n uint256 currRound = currentRound();\n\n // Check if already called for the current round\n require(lastInitializedRound < currRound, \"round already initialized\");\n\n // Set current round as initialized\n lastInitializedRound = currRound;\n // Store block hash for round\n bytes32 roundBlockHash = blockHash(blockNum().sub(1));\n _blockHashForRound[currRound] = roundBlockHash;\n // Set total active stake for the round\n bondingManager().setCurrentRoundTotalActiveStake();\n // Set mintable rewards for the round\n minter().setCurrentRewardTokens();\n\n emit NewRound(currRound, roundBlockHash);\n }\n\n /**\n * @notice setLIPUpgradeRound sets the round an LIP upgrade would become active.\n * @param _lip the LIP number.\n * @param _round (optional) the round in which the LIP becomes active\n */\n function setLIPUpgradeRound(uint256 _lip, uint256 _round) external onlyControllerOwner {\n require(lipUpgradeRound[_lip] == 0, \"LIP upgrade round already set\");\n lipUpgradeRound[_lip] = _round;\n }\n\n /**\n * @notice Return current block number\n */\n function blockNum() public view virtual returns (uint256) {\n return block.number;\n }\n\n /**\n * @notice Return blockhash for a block\n */\n function blockHash(uint256 _block) public view virtual returns (bytes32) {\n uint256 currentBlock = blockNum();\n require(_block < currentBlock, \"can only retrieve past block hashes\");\n require(currentBlock < 256 || _block >= currentBlock - 256, \"can only retrieve hashes for last 256 blocks\");\n\n return blockhash(_block);\n }\n\n /**\n * @notice Return blockhash for a round\n * @param _round Round number\n * @return Blockhash for `_round`\n */\n function blockHashForRound(uint256 _round) public view returns (bytes32) {\n return _blockHashForRound[_round];\n }\n\n /**\n * @notice Return current round\n */\n function currentRound() public view returns (uint256) {\n // Compute # of rounds since roundLength was last updated\n uint256 roundsSinceUpdate = blockNum().sub(lastRoundLengthUpdateStartBlock).div(roundLength);\n // Current round = round that roundLength was last updated + # of rounds since roundLength was last updated\n return lastRoundLengthUpdateRound.add(roundsSinceUpdate);\n }\n\n /**\n * @notice Return start block of current round\n */\n function currentRoundStartBlock() public view returns (uint256) {\n // Compute # of rounds since roundLength was last updated\n uint256 roundsSinceUpdate = blockNum().sub(lastRoundLengthUpdateStartBlock).div(roundLength);\n // Current round start block = start block of round that roundLength was last updated + (# of rounds since roundLenght was last updated * roundLength)\n return lastRoundLengthUpdateStartBlock.add(roundsSinceUpdate.mul(roundLength));\n }\n\n /**\n * @notice Check if current round is initialized\n */\n function currentRoundInitialized() public view returns (bool) {\n return lastInitializedRound == currentRound();\n }\n\n /**\n * @notice Check if we are in the lock period of the current round\n */\n function currentRoundLocked() public view returns (bool) {\n uint256 lockedBlocks = MathUtils.percOf(roundLength, roundLockAmount);\n return blockNum().sub(currentRoundStartBlock()) >= roundLength.sub(lockedBlocks);\n }\n\n /**\n * @dev Return BondingManager interface\n */\n function bondingManager() internal view returns (IBondingManager) {\n return IBondingManager(controller.getContract(keccak256(\"BondingManager\")));\n }\n\n /**\n * @dev Return Minter interface\n */\n function minter() internal view returns (IMinter) {\n return IMinter(controller.getContract(keccak256(\"Minter\")));\n }\n}\n" + }, + "contracts/test/TestMathUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../libraries/MathUtils.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestMathUtils {\n function test_validPerc() public {\n Assert.equal(MathUtils.validPerc(50), true, \"50 should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(0), true, \"0 should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(1000000), true, \"the max should be a valid percentage\");\n Assert.equal(MathUtils.validPerc(1000001), false, \"1 more than the max should not be valid percentage\");\n }\n\n function test_percOf1() public {\n Assert.equal(MathUtils.percOf(100, 3, 4), 75, \"3/4 of 100 should be 75\");\n Assert.equal(MathUtils.percOf(100, 7, 9), 77, \"7/9 of 100 should be 77\");\n }\n\n function test_percOf2() public {\n Assert.equal(MathUtils.percOf(100, 3), 0, \".0003% of 100 is 0\");\n Assert.equal(MathUtils.percOf(100, 100000), 10, \"10% of 100 is 10\");\n }\n\n function test_percPoints() public {\n Assert.equal(MathUtils.percPoints(3, 4), 750000, \"3/4 should convert to valid percentage\");\n Assert.equal(MathUtils.percPoints(100, 300), 333333, \"100/300 should convert to valid percentage\");\n }\n}\n" + }, + "contracts/test/mocks/EarningsPoolFixture.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../libraries/MathUtils.sol\";\nimport \"../../bonding/libraries/EarningsPool.sol\";\nimport \"../../bonding/libraries/EarningsPoolLIP36.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\ncontract EarningsPoolFixture {\n using SafeMath for uint256;\n using EarningsPool for EarningsPool.Data;\n using EarningsPoolLIP36 for EarningsPool.Data;\n\n EarningsPool.Data prevPool;\n EarningsPool.Data pool;\n\n function setCommission(uint256 _rewardCut, uint256 _feeShare) public {\n pool.setCommission(_rewardCut, _feeShare);\n }\n\n function setStake(uint256 _stake) public {\n pool.setStake(_stake);\n }\n\n function updateCumulativeFeeFactor(uint256 _fees) public {\n pool.updateCumulativeFeeFactor(prevPool, _fees);\n }\n\n function updateCumulativeRewardFactor(uint256 _rewards) public {\n pool.updateCumulativeRewardFactor(prevPool, _rewards);\n }\n\n function setPrevPoolEarningsFactors(uint256 _cumulativeFeeFactor, uint256 _cumulativeRewardFactor) public {\n prevPool.cumulativeFeeFactor = _cumulativeFeeFactor;\n prevPool.cumulativeRewardFactor = _cumulativeRewardFactor;\n }\n\n function setEarningsFactors(uint256 _cumulativeFeeFactor, uint256 _cumulativeRewardFactor) public {\n pool.cumulativeFeeFactor = _cumulativeFeeFactor;\n pool.cumulativeRewardFactor = _cumulativeRewardFactor;\n }\n\n function getTranscoderRewardCut() public view returns (uint256) {\n return pool.transcoderRewardCut;\n }\n\n function getTranscoderFeeShare() public view returns (uint256) {\n return pool.transcoderFeeShare;\n }\n\n function getTotalStake() public view returns (uint256) {\n return pool.totalStake;\n }\n\n function getCumulativeRewardFactor() public view returns (uint256) {\n return pool.cumulativeRewardFactor;\n }\n\n function getCumulativeFeeFactor() public view returns (uint256) {\n return pool.cumulativeFeeFactor;\n }\n\n function delegatorCumulativeStake(uint256 _stake) public view returns (uint256) {\n return EarningsPoolLIP36.delegatorCumulativeStake(prevPool, pool, _stake);\n }\n\n function delegatorCumulativeFees(uint256 _stake, uint256 _fees) public view returns (uint256) {\n return EarningsPoolLIP36.delegatorCumulativeFees(prevPool, pool, _stake, _fees);\n }\n\n function delegatorCumulativeStakeAndFees(uint256 _stake, uint256 _fees)\n public\n view\n returns (uint256 cStake, uint256 cFees)\n {\n return EarningsPoolLIP36.delegatorCumulativeStakeAndFees(prevPool, pool, _stake, _fees);\n }\n}\n" + }, + "contracts/test/TestEarningsPoolLIP36.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/EarningsPoolFixture.sol\";\nimport \"./helpers/truffle/Assert.sol\";\nimport \"../libraries/PreciseMathUtils.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\ncontract TestEarningsPoolLIP36 {\n using SafeMath for uint256;\n\n EarningsPoolFixture fixture;\n\n function beforeEach() public {\n fixture = new EarningsPoolFixture();\n fixture.setStake(1000);\n fixture.setCommission(500000, 500000);\n }\n\n function test_updateCumulativeFeeFactor_no_prevEarningsPool() public {\n uint256 fees = 1000;\n\n // earningsPool.cumulativeFeeFactor == 0\n // prevEarningsPool.cumulativeFeeFactor == 0\n // prevEarningsPool.cumulativeRewardFactor == 0\n fixture.updateCumulativeFeeFactor(fees);\n uint256 expFeeFactor = PreciseMathUtils.percPoints(fees, fixture.getTotalStake());\n Assert.equal(fixture.getCumulativeFeeFactor(), expFeeFactor, \"should set cumulativeFeeFactor\");\n\n // earningsPool.cumulativeFeeFactor != 0\n fixture.updateCumulativeFeeFactor(fees);\n expFeeFactor = expFeeFactor.add(PreciseMathUtils.percPoints(fees, fixture.getTotalStake()));\n Assert.equal(fixture.getCumulativeFeeFactor(), expFeeFactor, \"should update cumulativeFeeFactor\");\n }\n\n function test_updateCumulativeFeeFactor_prevEarningsPool() public {\n uint256 fees = 200;\n\n // prevEarningsPool.cumulativeFeeFactor = 2\n // prevEarningsPool.cumulativeRewardFactor = 3\n uint256 prevFeeFactor = 2;\n uint256 prevRewFactor = 3;\n fixture.setPrevPoolEarningsFactors(prevFeeFactor, prevRewFactor);\n\n // earningsPool.cumulativeFeeFactor == 0\n fixture.updateCumulativeFeeFactor(fees);\n uint256 expFeeFactor = prevFeeFactor.add(PreciseMathUtils.percOf(prevRewFactor, fees, fixture.getTotalStake()));\n Assert.equal(fixture.getCumulativeFeeFactor(), expFeeFactor, \"should update cumulativeFeeFactor\");\n\n // earningsPool.cumulativeFeeFactor != 0\n fixture.updateCumulativeFeeFactor(fees);\n expFeeFactor = expFeeFactor.add(PreciseMathUtils.percOf(prevRewFactor, fees, fixture.getTotalStake()));\n }\n\n function test_updateCumulativeRewardFactor() public {\n uint256 rewards = 1000;\n\n // prevEarningsPool.cumulativeRewardFactor == 0\n uint256 expRewardFactor = PreciseMathUtils.percPoints(1, 1).add(\n PreciseMathUtils.percOf(PreciseMathUtils.percPoints(1, 1), rewards, fixture.getTotalStake())\n );\n fixture.updateCumulativeRewardFactor(1000);\n Assert.equal(expRewardFactor, fixture.getCumulativeRewardFactor(), \"incorrect cumulative reward factor\");\n\n // prevEarningsPool.cumulativeRewardFactor != 0\n fixture.setPrevPoolEarningsFactors(0, expRewardFactor);\n expRewardFactor = expRewardFactor.add(\n PreciseMathUtils.percOf(expRewardFactor, rewards, fixture.getTotalStake())\n );\n fixture.updateCumulativeRewardFactor(1000);\n Assert.equal(expRewardFactor, fixture.getCumulativeRewardFactor(), \"incorrect cumulative reward factor\");\n }\n\n function test_delegatorCumulativeFees() public {\n uint256 stake = 1000;\n uint256 fees = 10;\n\n // all zeroed factors, should just return current fees\n Assert.equal(10, fixture.delegatorCumulativeFees(stake, fees), \"incorrect delegator cumulative fees\");\n\n fixture.setPrevPoolEarningsFactors(3, 2);\n fixture.setEarningsFactors(3, 2);\n\n // no increased fee factor yet, should still return current fees\n Assert.equal(10, fixture.delegatorCumulativeFees(stake, fees), \"incorrect delegator cumulative fees\");\n\n fixture.setEarningsFactors(6, 0); // end pool reward factor should not be used, set as 0\n\n // earned fees = 1000 * (6 - 3) / 2 = 1500\n Assert.equal(1510, fixture.delegatorCumulativeFees(stake, fees), \"incorrect delegator cumulative fees\");\n }\n\n function test_delegatorCumulativeStake() public {\n uint256 stake = 1000;\n\n // all zeroed factors, should just return current stake\n Assert.equal(1000, fixture.delegatorCumulativeStake(stake), \"incorrect delegator cumulative stake\");\n\n fixture.setPrevPoolEarningsFactors(0, 4);\n fixture.setEarningsFactors(0, 4);\n\n // no increased reward factor yet, should still return current stake\n Assert.equal(1000, fixture.delegatorCumulativeStake(stake), \"incorrect delegator cumulative stake\");\n\n fixture.setEarningsFactors(0, 10);\n\n // stake = 1000 * 10 / 4 = 2500\n Assert.equal(2500, fixture.delegatorCumulativeStake(stake), \"incorrect delegator cumulative stake\");\n }\n\n function test_delegatorCumulativeStakeAndFees() public {\n uint256 stake = 1000;\n uint256 fees = 10;\n\n // all zeroed factors, should just return current stake\n (uint256 cStake, uint256 cFees) = fixture.delegatorCumulativeStakeAndFees(stake, fees);\n Assert.equal(1000, cStake, \"incorrect delegator cumulative stake\");\n Assert.equal(10, cFees, \"incorrect delegator cumulative fee\");\n\n fixture.setPrevPoolEarningsFactors(2, 5);\n fixture.setEarningsFactors(2, 5);\n\n // no increased factors yet, should still return current values\n (cStake, cFees) = fixture.delegatorCumulativeStakeAndFees(stake, fees);\n Assert.equal(1000, cStake, \"incorrect delegator cumulative stake\");\n Assert.equal(10, cFees, \"incorrect delegator cumulative fee\");\n\n fixture.setEarningsFactors(5, 15);\n\n (cStake, cFees) = fixture.delegatorCumulativeStakeAndFees(stake, fees);\n // stake = 1000 * 15 / 5 = 3000\n Assert.equal(3000, cStake, \"incorrect delegator cumulative stake\");\n // earned fees = 1000 * (5 - 2) / 5 = 600\n Assert.equal(610, cFees, \"incorrect delegator cumulative fee\");\n }\n}\n" + }, + "contracts/test/TestPreciseMathUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../libraries/PreciseMathUtils.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestPreciseMathUtils {\n function test_validPerc() public {\n Assert.equal(PreciseMathUtils.validPerc(50), true, \"50 should be a valid percentage\");\n Assert.equal(PreciseMathUtils.validPerc(0), true, \"0 should be a valid percentage\");\n Assert.equal(PreciseMathUtils.validPerc(10**27), true, \"the max should be a valid percentage\");\n Assert.equal(\n PreciseMathUtils.validPerc(10**27 + 1),\n false,\n \"1 more than the max should not be valid percentage\"\n );\n }\n\n function test_percOf1() public {\n Assert.equal(PreciseMathUtils.percOf(100, 3, 4), 75, \"3/4 of 100 should be 75\");\n Assert.equal(PreciseMathUtils.percOf(100, 7, 9), 77, \"7/9 of 100 should be 77\");\n }\n\n function test_percOf2() public {\n Assert.equal(PreciseMathUtils.percOf(100, 3), 0, \".0000000000000000000000003% of 100 is 0\");\n Assert.equal(PreciseMathUtils.percOf(10**27, 1), 1, \".0000000000000000000000001% of 1000000000 is 1\");\n Assert.equal(PreciseMathUtils.percOf(100, 10**27 / 10), 10, \"10% of 100 is 10\");\n }\n\n function test_percPoints() public {\n Assert.equal(\n PreciseMathUtils.percPoints(3, 4),\n 750000000000000000000000000,\n \"3/4 should convert to valid percentage\"\n );\n Assert.equal(\n PreciseMathUtils.percPoints(100, 300),\n 333333333333333333333333333,\n \"100/300 should convert to valid percentage\"\n );\n }\n}\n" + }, + "contracts/test/TestEarningsPool.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mocks/EarningsPoolFixture.sol\";\nimport \"./helpers/truffle/Assert.sol\";\n\ncontract TestEarningsPool {\n EarningsPoolFixture fixture;\n\n function beforeEach() public {\n fixture = new EarningsPoolFixture();\n fixture.setStake(1000);\n fixture.setCommission(500000, 500000);\n }\n\n function test_setCommission() public {\n fixture.setCommission(5, 10);\n uint256 transcoderRewardCut = fixture.getTranscoderRewardCut();\n uint256 transcoderFeeShare = fixture.getTranscoderFeeShare();\n Assert.equal(transcoderRewardCut, 5, \"wrong transcoderRewardCut\");\n Assert.equal(transcoderFeeShare, 10, \"wrong transcoderFeeShare\");\n }\n\n function test_setStake() public {\n fixture.setStake(5000);\n uint256 totalStake = fixture.getTotalStake();\n Assert.equal(totalStake, 5000, \"wrong totalStake\");\n }\n}\n" + }, + "contracts/pm/mixins/interfaces/MContractRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../../bonding/IBondingManager.sol\";\nimport \"../../../token/IMinter.sol\";\nimport \"../../../rounds/IRoundsManager.sol\";\n\nabstract contract MContractRegistry {\n /**\n * @notice Checks if the current round has been initialized\n * @dev Executes the 'currentRoundInitialized' modifier in 'MixinContractRegistry'\n */\n modifier currentRoundInitialized() virtual {\n _;\n }\n\n /**\n * @dev Returns an instance of the IBondingManager interface\n */\n function bondingManager() internal view virtual returns (IBondingManager);\n\n /**\n * @dev Returns an instance of the IMinter interface\n */\n function minter() internal view virtual returns (IMinter);\n\n /**\n * @dev Returns an instance of the IRoundsManager interface\n */\n function roundsManager() internal view virtual returns (IRoundsManager);\n}\n" + }, + "contracts/pm/mixins/MixinContractRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../ManagerProxyTarget.sol\";\nimport \"./interfaces/MContractRegistry.sol\";\n\nabstract contract MixinContractRegistry is MContractRegistry, ManagerProxyTarget {\n /**\n * @dev Checks if the current round has been initialized\n */\n modifier currentRoundInitialized() override {\n require(roundsManager().currentRoundInitialized(), \"current round is not initialized\");\n _;\n }\n\n constructor(address _controller) Manager(_controller) {}\n\n /**\n * @dev Returns an instance of the IBondingManager interface\n */\n function bondingManager() internal view override returns (IBondingManager) {\n return IBondingManager(controller.getContract(keccak256(\"BondingManager\")));\n }\n\n /**\n * @dev Returns an instance of the IMinter interface\n */\n function minter() internal view override returns (IMinter) {\n return IMinter(controller.getContract(keccak256(\"Minter\")));\n }\n\n /**\n * @dev Returns an instance of the IRoundsManager interface\n */\n function roundsManager() internal view override returns (IRoundsManager) {\n return IRoundsManager(controller.getContract(keccak256(\"RoundsManager\")));\n }\n}\n" + }, + "contracts/pm/TicketBroker.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./mixins/MixinContractRegistry.sol\";\nimport \"./mixins/MixinReserve.sol\";\nimport \"./mixins/MixinTicketBrokerCore.sol\";\nimport \"./mixins/MixinTicketProcessor.sol\";\nimport \"./mixins/MixinWrappers.sol\";\n\ncontract TicketBroker is\n MixinContractRegistry,\n MixinReserve,\n MixinTicketBrokerCore,\n MixinTicketProcessor,\n MixinWrappers\n{\n /**\n * @notice TicketBroker constructor. Only invokes constructor of base Manager contract with provided Controller address\n * @dev This constructor will not initialize any state variables besides `controller`. The following setter functions\n * should be used to initialize state variables post-deployment:\n * - setUnlockPeriod()\n * - setTicketValidityPeriod()\n * @param _controller Address of Controller that this contract will be registered with\n */\n constructor(address _controller)\n MixinContractRegistry(_controller)\n MixinReserve()\n MixinTicketBrokerCore()\n MixinTicketProcessor()\n {}\n\n /**\n * @notice Sets unlockPeriod value. Only callable by the Controller owner\n * @param _unlockPeriod Value for unlockPeriod\n */\n function setUnlockPeriod(uint256 _unlockPeriod) external onlyControllerOwner {\n unlockPeriod = _unlockPeriod;\n\n emit ParameterUpdate(\"unlockPeriod\");\n }\n\n /**\n * @notice Sets ticketValidityPeriod value. Only callable by the Controller owner\n * @param _ticketValidityPeriod Value for ticketValidityPeriod\n */\n function setTicketValidityPeriod(uint256 _ticketValidityPeriod) external onlyControllerOwner {\n require(_ticketValidityPeriod > 0, \"ticketValidityPeriod must be greater than 0\");\n\n ticketValidityPeriod = _ticketValidityPeriod;\n\n emit ParameterUpdate(\"ticketValidityPeriod\");\n }\n}\n" + }, + "contracts/pm/mixins/MixinReserve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./interfaces/MReserve.sol\";\nimport \"./MixinContractRegistry.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nabstract contract MixinReserve is MixinContractRegistry, MReserve {\n using SafeMath for uint256;\n\n struct Reserve {\n uint256 funds; // Amount of funds in the reserve\n mapping(uint256 => uint256) claimedForRound; // Mapping of round => total amount claimed\n mapping(uint256 => mapping(address => uint256)) claimedByAddress; // Mapping of round => claimant address => amount claimed\n }\n\n // Mapping of address => reserve\n mapping(address => Reserve) internal reserves;\n\n /**\n * @dev Returns info about a reserve\n * @param _reserveHolder Address of reserve holder\n * @return info Info about the reserve for `_reserveHolder`\n */\n function getReserveInfo(address _reserveHolder) public view override returns (ReserveInfo memory info) {\n info.fundsRemaining = remainingReserve(_reserveHolder);\n info.claimedInCurrentRound = reserves[_reserveHolder].claimedForRound[roundsManager().currentRound()];\n }\n\n /**\n * @dev Returns the amount of funds claimable by a claimant from a reserve in the current round\n * @param _reserveHolder Address of reserve holder\n * @param _claimant Address of claimant\n * @return Amount of funds claimable by `_claimant` from the reserve for `_reserveHolder` in the current round\n */\n function claimableReserve(address _reserveHolder, address _claimant) public view returns (uint256) {\n Reserve storage reserve = reserves[_reserveHolder];\n\n uint256 currentRound = roundsManager().currentRound();\n\n if (!bondingManager().isActiveTranscoder(_claimant)) {\n return 0;\n }\n\n uint256 poolSize = bondingManager().getTranscoderPoolSize();\n if (poolSize == 0) {\n return 0;\n }\n\n // Total claimable funds = remaining funds + amount claimed for the round\n uint256 totalClaimable = reserve.funds.add(reserve.claimedForRound[currentRound]);\n return totalClaimable.div(poolSize).sub(reserve.claimedByAddress[currentRound][_claimant]);\n }\n\n /**\n * @dev Returns the amount of funds claimed by a claimant from a reserve in the current round\n * @param _reserveHolder Address of reserve holder\n * @param _claimant Address of claimant\n * @return Amount of funds claimed by `_claimant` from the reserve for `_reserveHolder` in the current round\n */\n function claimedReserve(address _reserveHolder, address _claimant) public view override returns (uint256) {\n Reserve storage reserve = reserves[_reserveHolder];\n uint256 currentRound = roundsManager().currentRound();\n return reserve.claimedByAddress[currentRound][_claimant];\n }\n\n /**\n * @dev Adds funds to a reserve\n * @param _reserveHolder Address of reserve holder\n * @param _amount Amount of funds to add to reserve\n */\n function addReserve(address _reserveHolder, uint256 _amount) internal override {\n reserves[_reserveHolder].funds = reserves[_reserveHolder].funds.add(_amount);\n\n emit ReserveFunded(_reserveHolder, _amount);\n }\n\n /**\n * @dev Clears contract storage used for a reserve\n * @param _reserveHolder Address of reserve holder\n */\n function clearReserve(address _reserveHolder) internal override {\n // This delete operation will only clear reserve.funds and will not clear the storage for reserve.claimedForRound\n // reserve.claimedByAddress because these fields are mappings and the Solidity `delete` keyword will not modify mappings.\n // This *could* be a problem in the following scenario:\n //\n // 1) In round N, for address A, reserve.claimedForRound[N] > 0 and reserve.claimedByAddress[N][r_i] > 0 where r_i is\n // a member of the active set in round N\n // 2) This function is called by MixinTicketBrokerCore.withdraw() in round N\n // 3) Address A funds its reserve again\n //\n // After step 3, A has reserve.funds > 0, reserve.claimedForRound[N] > 0 and reserve.claimedByAddress[N][r_i] > 0\n // despite having funded a fresh reserve after previously withdrawing all of its funds in the same round.\n // We prevent this scenario by disallowing reserve claims starting at an address' withdraw round in\n // MixinTicketBrokerCore.redeemWinningTicket()\n delete reserves[_reserveHolder];\n }\n\n /**\n * @dev Claims funds from a reserve\n * @param _reserveHolder Address of reserve holder\n * @param _claimant Address of claimant\n * @param _amount Amount of funds to claim from the reserve\n * @return Amount of funds (<= `_amount`) claimed by `_claimant` from the reserve for `_reserveHolder`\n */\n function claimFromReserve(\n address _reserveHolder,\n address _claimant,\n uint256 _amount\n ) internal override returns (uint256) {\n uint256 claimableFunds = claimableReserve(_reserveHolder, _claimant);\n // If the given amount > claimableFunds then claim claimableFunds\n // If the given amount <= claimableFunds then claim the given amount\n uint256 claimAmount = _amount > claimableFunds ? claimableFunds : _amount;\n\n if (claimAmount > 0) {\n uint256 currentRound = roundsManager().currentRound();\n Reserve storage reserve = reserves[_reserveHolder];\n // Increase total amount claimed for the round\n reserve.claimedForRound[currentRound] = reserve.claimedForRound[currentRound].add(claimAmount);\n // Increase amount claimed by claimant for the round\n reserve.claimedByAddress[currentRound][_claimant] = reserve.claimedByAddress[currentRound][_claimant].add(\n claimAmount\n );\n // Decrease remaining reserve\n reserve.funds = reserve.funds.sub(claimAmount);\n\n emit ReserveClaimed(_reserveHolder, _claimant, claimAmount);\n }\n\n return claimAmount;\n }\n\n /**\n * @dev Returns the amount of funds remaining in a reserve\n * @param _reserveHolder Address of reserve holder\n * @return Amount of funds remaining in the reserve for `_reserveHolder`\n */\n function remainingReserve(address _reserveHolder) internal view override returns (uint256) {\n return reserves[_reserveHolder].funds;\n }\n}\n" + }, + "contracts/pm/mixins/MixinTicketBrokerCore.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./interfaces/MReserve.sol\";\nimport \"./interfaces/MTicketProcessor.sol\";\nimport \"./interfaces/MTicketBrokerCore.sol\";\nimport \"./MixinContractRegistry.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nabstract contract MixinTicketBrokerCore is MixinContractRegistry, MReserve, MTicketProcessor, MTicketBrokerCore {\n using SafeMath for uint256;\n\n struct Sender {\n uint256 deposit; // Amount of funds deposited\n uint256 withdrawRound; // Round that sender can withdraw deposit & reserve\n }\n\n // Mapping of address => Sender\n mapping(address => Sender) internal senders;\n\n // Number of rounds before a sender can withdraw after requesting an unlock\n uint256 public unlockPeriod;\n\n // Mapping of ticket hashes => boolean indicating if ticket was redeemed\n mapping(bytes32 => bool) public usedTickets;\n\n // Checks if msg.value is equal to the given deposit and reserve amounts\n modifier checkDepositReserveETHValueSplit(uint256 _depositAmount, uint256 _reserveAmount) {\n require(\n msg.value == _depositAmount.add(_reserveAmount),\n \"msg.value does not equal sum of deposit amount and reserve amount\"\n );\n\n _;\n }\n\n // Process deposit funding\n modifier processDeposit(address _sender, uint256 _amount) {\n Sender storage sender = senders[_sender];\n sender.deposit = sender.deposit.add(_amount);\n // If the sender themselves funds their deposit, cancel the unlock\n if (msg.sender == _sender && _isUnlockInProgress(sender)) {\n _cancelUnlock(sender, _sender);\n }\n\n _;\n\n emit DepositFunded(_sender, _amount);\n }\n\n // Process reserve funding\n modifier processReserve(address _sender, uint256 _amount) {\n Sender storage sender = senders[_sender];\n addReserve(_sender, _amount);\n // If the sender themselves funds their reserve, cancel the unlock\n if (msg.sender == _sender && _isUnlockInProgress(sender)) {\n _cancelUnlock(sender, _sender);\n }\n\n _;\n }\n\n /**\n * @notice Adds ETH to the caller's deposit\n */\n function fundDeposit() external payable whenSystemNotPaused processDeposit(msg.sender, msg.value) {\n processFunding(msg.value);\n }\n\n /**\n * @notice Adds ETH to the caller's reserve\n */\n function fundReserve() external payable whenSystemNotPaused processReserve(msg.sender, msg.value) {\n processFunding(msg.value);\n }\n\n /**\n * @notice Adds ETH to the caller's deposit and reserve\n * @param _depositAmount Amount of ETH to add to the caller's deposit\n * @param _reserveAmount Amount of ETH to add to the caller's reserve\n */\n function fundDepositAndReserve(uint256 _depositAmount, uint256 _reserveAmount) external payable {\n fundDepositAndReserveFor(msg.sender, _depositAmount, _reserveAmount);\n }\n\n /**\n * @notice Adds ETH to the address' deposit and reserve\n * @param _depositAmount Amount of ETH to add to the address' deposit\n * @param _reserveAmount Amount of ETH to add to the address' reserve\n */\n function fundDepositAndReserveFor(\n address _addr,\n uint256 _depositAmount,\n uint256 _reserveAmount\n )\n public\n payable\n whenSystemNotPaused\n checkDepositReserveETHValueSplit(_depositAmount, _reserveAmount)\n processDeposit(_addr, _depositAmount)\n processReserve(_addr, _reserveAmount)\n {\n processFunding(msg.value);\n }\n\n /**\n * @notice Redeems a winning ticket that has been signed by a sender and reveals the\n recipient recipientRand that corresponds to the recipientRandHash included in the ticket\n * @param _ticket Winning ticket to be redeemed in order to claim payment\n * @param _sig Sender's signature over the hash of `_ticket`\n * @param _recipientRand The preimage for the recipientRandHash included in `_ticket`\n */\n function redeemWinningTicket(\n Ticket memory _ticket,\n bytes memory _sig,\n uint256 _recipientRand\n ) public whenSystemNotPaused currentRoundInitialized {\n bytes32 ticketHash = getTicketHash(_ticket);\n\n // Require a valid winning ticket for redemption\n requireValidWinningTicket(_ticket, ticketHash, _sig, _recipientRand);\n\n Sender storage sender = senders[_ticket.sender];\n\n // Require sender to be locked\n require(isLocked(sender), \"sender is unlocked\");\n // Require either a non-zero deposit or non-zero reserve for the sender\n require(sender.deposit > 0 || remainingReserve(_ticket.sender) > 0, \"sender deposit and reserve are zero\");\n\n // Mark ticket as used to prevent replay attacks involving redeeming\n // the same winning ticket multiple times\n usedTickets[ticketHash] = true;\n\n uint256 amountToTransfer;\n\n if (_ticket.faceValue > sender.deposit) {\n // If ticket face value > sender's deposit then claim from\n // the sender's reserve\n\n amountToTransfer = sender.deposit.add(\n claimFromReserve(_ticket.sender, _ticket.recipient, _ticket.faceValue.sub(sender.deposit))\n );\n\n sender.deposit = 0;\n } else {\n // If ticket face value <= sender's deposit then only deduct\n // from sender's deposit\n\n amountToTransfer = _ticket.faceValue;\n sender.deposit = sender.deposit.sub(_ticket.faceValue);\n }\n\n if (amountToTransfer > 0) {\n winningTicketTransfer(_ticket.recipient, amountToTransfer, _ticket.auxData);\n\n emit WinningTicketTransfer(_ticket.sender, _ticket.recipient, amountToTransfer);\n }\n\n emit WinningTicketRedeemed(\n _ticket.sender,\n _ticket.recipient,\n _ticket.faceValue,\n _ticket.winProb,\n _ticket.senderNonce,\n _recipientRand,\n _ticket.auxData\n );\n }\n\n /**\n * @notice Initiates the unlock period for the caller\n */\n function unlock() public whenSystemNotPaused {\n Sender storage sender = senders[msg.sender];\n\n require(sender.deposit > 0 || remainingReserve(msg.sender) > 0, \"sender deposit and reserve are zero\");\n require(!_isUnlockInProgress(sender), \"unlock already initiated\");\n\n uint256 currentRound = roundsManager().currentRound();\n sender.withdrawRound = currentRound.add(unlockPeriod);\n\n emit Unlock(msg.sender, currentRound, sender.withdrawRound);\n }\n\n /**\n * @notice Cancels the unlock period for the caller\n */\n function cancelUnlock() public whenSystemNotPaused {\n Sender storage sender = senders[msg.sender];\n\n _cancelUnlock(sender, msg.sender);\n }\n\n /**\n * @notice Withdraws all ETH from the caller's deposit and reserve\n */\n function withdraw() public whenSystemNotPaused {\n Sender storage sender = senders[msg.sender];\n\n uint256 deposit = sender.deposit;\n uint256 reserve = remainingReserve(msg.sender);\n\n require(deposit > 0 || reserve > 0, \"sender deposit and reserve are zero\");\n require(_isUnlockInProgress(sender), \"no unlock request in progress\");\n require(!isLocked(sender), \"account is locked\");\n\n sender.deposit = 0;\n clearReserve(msg.sender);\n\n withdrawTransfer(payable(msg.sender), deposit.add(reserve));\n\n emit Withdrawal(msg.sender, deposit, reserve);\n }\n\n /**\n * @notice Returns whether a sender is currently in the unlock period\n * @param _sender Address of sender\n * @return Boolean indicating whether `_sender` has an unlock in progress\n */\n function isUnlockInProgress(address _sender) public view returns (bool) {\n Sender memory sender = senders[_sender];\n return _isUnlockInProgress(sender);\n }\n\n /**\n * @notice Returns info about a sender\n * @param _sender Address of sender\n * @return sender Info about the sender for `_sender`\n * @return reserve Info about the reserve for `_sender`\n */\n function getSenderInfo(address _sender) public view returns (Sender memory sender, ReserveInfo memory reserve) {\n sender = senders[_sender];\n reserve = getReserveInfo(_sender);\n }\n\n /**\n * @dev Returns the hash of a ticket\n * @param _ticket Ticket to be hashed\n * @return keccak256 hash of `_ticket`\n */\n function getTicketHash(Ticket memory _ticket) public pure returns (bytes32) {\n return\n keccak256(\n abi.encodePacked(\n _ticket.recipient,\n _ticket.sender,\n _ticket.faceValue,\n _ticket.winProb,\n _ticket.senderNonce,\n _ticket.recipientRandHash,\n _ticket.auxData\n )\n );\n }\n\n /**\n * @dev Helper to cancel an unlock\n * @param _sender Sender that is cancelling an unlock\n * @param _senderAddress Address of sender\n */\n function _cancelUnlock(Sender storage _sender, address _senderAddress) internal {\n require(_isUnlockInProgress(_sender), \"no unlock request in progress\");\n\n _sender.withdrawRound = 0;\n\n emit UnlockCancelled(_senderAddress);\n }\n\n /**\n * @dev Validates a winning ticket, succeeds or reverts\n * @param _ticket Winning ticket to be validated\n * @param _ticketHash Hash of `_ticket`\n * @param _sig Sender's signature over `_ticketHash`\n * @param _recipientRand The preimage for the recipientRandHash included in `_ticket`\n */\n function requireValidWinningTicket(\n Ticket memory _ticket,\n bytes32 _ticketHash,\n bytes memory _sig,\n uint256 _recipientRand\n ) internal view {\n require(_ticket.recipient != address(0), \"ticket recipient is null address\");\n require(_ticket.sender != address(0), \"ticket sender is null address\");\n\n requireValidTicketAuxData(_ticket.auxData);\n\n require(\n keccak256(abi.encodePacked(_recipientRand)) == _ticket.recipientRandHash,\n \"recipientRand does not match recipientRandHash\"\n );\n\n require(!usedTickets[_ticketHash], \"ticket is used\");\n\n require(isValidTicketSig(_ticket.sender, _sig, _ticketHash), \"invalid signature over ticket hash\");\n\n require(isWinningTicket(_sig, _recipientRand, _ticket.winProb), \"ticket did not win\");\n }\n\n /**\n * @dev Returns whether a sender is locked\n * @param _sender Sender to check for locked status\n * @return Boolean indicating whether sender is currently locked\n */\n function isLocked(Sender memory _sender) internal view returns (bool) {\n return _sender.withdrawRound == 0 || roundsManager().currentRound() < _sender.withdrawRound;\n }\n\n /**\n * @dev Returns whether a signature over a ticket hash is valid for a sender\n * @param _sender Address of sender\n * @param _sig Signature over `_ticketHash`\n * @param _ticketHash Hash of the ticket\n * @return Boolean indicating whether `_sig` is valid signature over `_ticketHash` for `_sender`\n */\n function isValidTicketSig(\n address _sender,\n bytes memory _sig,\n bytes32 _ticketHash\n ) internal pure returns (bool) {\n require(_sig.length == 65, \"INVALID_SIGNATURE_LENGTH\");\n address signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(_ticketHash), _sig);\n return signer != address(0) && _sender == signer;\n }\n\n /**\n * @dev Returns whether a ticket won\n * @param _sig Sender's signature over the ticket\n * @param _recipientRand The preimage for the recipientRandHash included in the ticket\n * @param _winProb The winning probability of the ticket\n * @return Boolean indicating whether the ticket won\n */\n function isWinningTicket(\n bytes memory _sig,\n uint256 _recipientRand,\n uint256 _winProb\n ) internal pure returns (bool) {\n return uint256(keccak256(abi.encodePacked(_sig, _recipientRand))) < _winProb;\n }\n\n /**\n * @dev Helper to check if a sender is currently in the unlock period\n * @param _sender Sender to check for an unlock\n * @return Boolean indicating whether the sender is currently in the unlock period\n */\n function _isUnlockInProgress(Sender memory _sender) internal pure returns (bool) {\n return _sender.withdrawRound > 0;\n }\n}\n" + }, + "contracts/pm/mixins/MixinTicketProcessor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./interfaces/MTicketProcessor.sol\";\nimport \"./MixinContractRegistry.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\nabstract contract MixinTicketProcessor is MixinContractRegistry, MTicketProcessor {\n using SafeMath for uint256;\n\n // Number of rounds that a ticket is valid for starting from\n // its creationRound\n uint256 public ticketValidityPeriod;\n\n /**\n * @dev Process sent funds.\n * @param _amount Amount of funds sent\n */\n function processFunding(uint256 _amount) internal override {\n // Send funds to Minter\n minter().depositETH{ value: _amount }();\n }\n\n /**\n * @dev Transfer withdrawal funds for a ticket sender\n * @param _amount Amount of withdrawal funds\n */\n function withdrawTransfer(address payable _sender, uint256 _amount) internal override {\n // Ask Minter to send withdrawal funds to the ticket sender\n minter().trustedWithdrawETH(_sender, _amount);\n }\n\n /**\n * @dev Transfer funds for a recipient's winning ticket\n * @param _recipient Address of recipient\n * @param _amount Amount of funds for the winning ticket\n * @param _auxData Auxilary data for the winning ticket\n */\n function winningTicketTransfer(\n address _recipient,\n uint256 _amount,\n bytes memory _auxData\n ) internal override {\n (uint256 creationRound, ) = getCreationRoundAndBlockHash(_auxData);\n\n // Ask BondingManager to update fee pool for recipient with\n // winning ticket funds\n bondingManager().updateTranscoderWithFees(_recipient, _amount, creationRound);\n }\n\n /**\n * @dev Validates a ticket's auxilary data (succeeds or reverts)\n * @param _auxData Auxilary data inclueded in a ticket\n */\n function requireValidTicketAuxData(bytes memory _auxData) internal view override {\n (uint256 creationRound, bytes32 creationRoundBlockHash) = getCreationRoundAndBlockHash(_auxData);\n bytes32 blockHash = roundsManager().blockHashForRound(creationRound);\n\n require(blockHash != bytes32(0), \"ticket creationRound does not have a block hash\");\n require(creationRoundBlockHash == blockHash, \"ticket creationRoundBlockHash invalid for creationRound\");\n\n uint256 currRound = roundsManager().currentRound();\n\n require(creationRound.add(ticketValidityPeriod) > currRound, \"ticket is expired\");\n }\n\n /**\n * @dev Returns a ticket's creationRound and creationRoundBlockHash parsed from ticket auxilary data\n * @param _auxData Auxilary data for a ticket\n * @return creationRound and creationRoundBlockHash parsed from `_auxData`\n */\n function getCreationRoundAndBlockHash(bytes memory _auxData)\n internal\n pure\n returns (uint256 creationRound, bytes32 creationRoundBlockHash)\n {\n require(_auxData.length == 64, \"invalid length for ticket auxData: must be 64 bytes\");\n\n // _auxData format:\n // Bytes [0:31] = creationRound\n // Bytes [32:63] = creationRoundBlockHash\n assembly {\n creationRound := mload(add(_auxData, 32))\n creationRoundBlockHash := mload(add(_auxData, 64))\n }\n }\n}\n" + }, + "contracts/pm/mixins/MixinWrappers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./interfaces/MTicketBrokerCore.sol\";\nimport \"./MixinContractRegistry.sol\";\n\nabstract contract MixinWrappers is MixinContractRegistry, MTicketBrokerCore {\n /**\n * @notice Redeems multiple winning tickets. The function will redeem all of the provided tickets and handle any failures gracefully without reverting the entire function\n * @param _tickets Array of winning tickets to be redeemed in order to claim payment\n * @param _sigs Array of sender signatures over the hash of tickets (`_sigs[i]` corresponds to `_tickets[i]`)\n * @param _recipientRands Array of preimages for the recipientRandHash included in each ticket (`_recipientRands[i]` corresponds to `_tickets[i]`)\n */\n function batchRedeemWinningTickets(\n Ticket[] memory _tickets,\n bytes[] memory _sigs,\n uint256[] memory _recipientRands\n ) public whenSystemNotPaused currentRoundInitialized {\n for (uint256 i = 0; i < _tickets.length; i++) {\n redeemWinningTicketNoRevert(_tickets[i], _sigs[i], _recipientRands[i]);\n }\n }\n\n /**\n * @dev Redeems a winning ticket that has been signed by a sender and reveals the\n recipient recipientRand that corresponds to the recipientRandHash included in the ticket\n This function wraps `redeemWinningTicket()` and returns false if the underlying call reverts\n * @param _ticket Winning ticket to be redeemed in order to claim payment\n * @param _sig Sender's signature over the hash of `_ticket`\n * @param _recipientRand The preimage for the recipientRandHash included in `_ticket`\n * @return success Boolean indicating whether the underlying `redeemWinningTicket()` call succeeded\n */\n function redeemWinningTicketNoRevert(\n Ticket memory _ticket,\n bytes memory _sig,\n uint256 _recipientRand\n ) internal returns (bool success) {\n // ABI encode calldata for `redeemWinningTicket()`\n // A tuple type is used to represent the Ticket struct in the function signature\n bytes memory redeemWinningTicketCalldata = abi.encodeWithSignature(\n \"redeemWinningTicket((address,address,uint256,uint256,uint256,bytes32,bytes),bytes,uint256)\",\n _ticket,\n _sig,\n _recipientRand\n );\n\n // Call `redeemWinningTicket()`\n // solium-disable-next-line\n (success, ) = address(this).call(redeemWinningTicketCalldata);\n }\n}\n" + }, + "contracts/pm/mixins/interfaces/MReserve.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nabstract contract MReserve {\n struct ReserveInfo {\n uint256 fundsRemaining; // Funds remaining in reserve\n uint256 claimedInCurrentRound; // Funds claimed from reserve in current round\n }\n\n // Emitted when funds are added to a reserve\n event ReserveFunded(address indexed reserveHolder, uint256 amount);\n // Emitted when funds are claimed from a reserve\n event ReserveClaimed(address indexed reserveHolder, address claimant, uint256 amount);\n\n /**\n * @notice Returns info about a reserve\n * @param _reserveHolder Address of reserve holder\n * @return info Info about the reserve for `_reserveHolder`\n */\n function getReserveInfo(address _reserveHolder) public view virtual returns (ReserveInfo memory info);\n\n /**\n * @notice Returns the amount of funds claimed by a claimant from a reserve\n * @param _reserveHolder Address of reserve holder\n * @param _claimant Address of claimant\n * @return Amount of funds claimed by `_claimant` from the reserve for `_reserveHolder`\n */\n function claimedReserve(address _reserveHolder, address _claimant) public view virtual returns (uint256);\n\n /**\n * @dev Adds funds to a reserve\n * @param _reserveHolder Address of reserve holder\n * @param _amount Amount of funds to add to reserve\n */\n function addReserve(address _reserveHolder, uint256 _amount) internal virtual;\n\n /**\n * @dev Clears contract storage used for a reserve\n * @param _reserveHolder Address of reserve holder\n */\n function clearReserve(address _reserveHolder) internal virtual;\n\n /**\n * @dev Claims funds from a reserve\n * @param _reserveHolder Address of reserve holder\n * @param _claimant Address of claimant\n * @param _amount Amount of funds to claim from the reserve\n * @return Amount of funds (<= `_amount`) claimed by `_claimant` from the reserve for `_reserveHolder`\n */\n function claimFromReserve(\n address _reserveHolder,\n address _claimant,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /**\n * @dev Returns the amount of funds remaining in a reserve\n * @param _reserveHolder Address of reserve holder\n * @return Amount of funds remaining in the reserve for `_reserveHolder`\n */\n function remainingReserve(address _reserveHolder) internal view virtual returns (uint256);\n}\n" + }, + "contracts/pm/mixins/interfaces/MTicketProcessor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nabstract contract MTicketProcessor {\n /**\n * @dev Process sent funds.\n * @param _amount Amount of funds sent\n */\n function processFunding(uint256 _amount) internal virtual;\n\n /**\n * @dev Transfer withdrawal funds for a ticket sender\n * @param _amount Amount of withdrawal funds\n */\n function withdrawTransfer(address payable _sender, uint256 _amount) internal virtual;\n\n /**\n * @dev Transfer funds for a recipient's winning ticket\n * @param _recipient Address of recipient\n * @param _amount Amount of funds for the winning ticket\n * @param _auxData Auxilary data for the winning ticket\n */\n function winningTicketTransfer(\n address _recipient,\n uint256 _amount,\n bytes memory _auxData\n ) internal virtual;\n\n /**\n * @dev Validates a ticket's auxilary data (succeeds or reverts)\n * @param _auxData Auxilary data inclueded in a ticket\n */\n function requireValidTicketAuxData(bytes memory _auxData) internal view virtual;\n}\n" + }, + "contracts/pm/mixins/interfaces/MTicketBrokerCore.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nabstract contract MTicketBrokerCore {\n struct Ticket {\n address recipient; // Address of ticket recipient\n address sender; // Address of ticket sender\n uint256 faceValue; // Face value of ticket paid to recipient if ticket wins\n uint256 winProb; // Probability ticket will win represented as winProb / (2^256 - 1)\n uint256 senderNonce; // Sender's monotonically increasing counter for each ticket\n bytes32 recipientRandHash; // keccak256 hash commitment to recipient's random value\n bytes auxData; // Auxilary data included in ticket used for additional validation\n }\n\n // Emitted when funds are added to a sender's deposit\n event DepositFunded(address indexed sender, uint256 amount);\n // Emitted when a winning ticket is redeemed\n event WinningTicketRedeemed(\n address indexed sender,\n address indexed recipient,\n uint256 faceValue,\n uint256 winProb,\n uint256 senderNonce,\n uint256 recipientRand,\n bytes auxData\n );\n // Emitted when a funds transfer for a winning ticket redemption is executed\n event WinningTicketTransfer(address indexed sender, address indexed recipient, uint256 amount);\n // Emitted when a sender requests an unlock\n event Unlock(address indexed sender, uint256 startRound, uint256 endRound);\n // Emitted when a sender cancels an unlock\n event UnlockCancelled(address indexed sender);\n // Emitted when a sender withdraws its deposit & reserve\n event Withdrawal(address indexed sender, uint256 deposit, uint256 reserve);\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "contracts/test/mocks/TicketBrokerExtendedMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\nimport \"../../pm/TicketBroker.sol\";\n\ncontract TickerBrokerExtendedMock is TicketBroker {\n constructor(address _controller) TicketBroker(_controller) {}\n\n function checkResult(bytes calldata _sig, uint256 _recipientRand) external pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(_sig, _recipientRand)));\n }\n\n function validateAndCheckTicketOutcome(\n address _sender,\n bytes32 _ticketHash,\n bytes calldata _sig,\n uint256 _recipientRand,\n uint256 _winProb\n ) external pure returns (bool) {\n require(isValidTicketSig(_sender, _sig, _ticketHash), \"invalid signature over ticket hash\");\n return isWinningTicket(_sig, _recipientRand, _winProb);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSA.sol\";\nimport \"../ShortStrings.sol\";\nimport \"../../interfaces/IERC5267.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n */\nabstract contract EIP712 is IERC5267 {\n using ShortStrings for *;\n\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _cachedDomainSeparator;\n uint256 private immutable _cachedChainId;\n address private immutable _cachedThis;\n\n bytes32 private immutable _hashedName;\n bytes32 private immutable _hashedVersion;\n\n ShortString private immutable _name;\n ShortString private immutable _version;\n string private _nameFallback;\n string private _versionFallback;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n _name = name.toShortStringWithFallback(_nameFallback);\n _version = version.toShortStringWithFallback(_versionFallback);\n _hashedName = keccak256(bytes(name));\n _hashedVersion = keccak256(bytes(version));\n\n _cachedChainId = block.chainid;\n _cachedDomainSeparator = _buildDomainSeparator();\n _cachedThis = address(this);\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _cachedThis && block.chainid == _cachedChainId) {\n return _cachedDomainSeparator;\n } else {\n return _buildDomainSeparator();\n }\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n return (\n hex\"0f\", // 01111\n _name.toStringWithFallback(_nameFallback),\n _version.toStringWithFallback(_versionFallback),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n}\n" + }, + "@openzeppelin/contracts/utils/ShortStrings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./StorageSlot.sol\";\n\n// | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |\n// | length | 0x BB |\ntype ShortString is bytes32;\n\n/**\n * @dev This library provides functions to convert short memory strings\n * into a `ShortString` type that can be used as an immutable variable.\n *\n * Strings of arbitrary length can be optimized using this library if\n * they are short enough (up to 31 bytes) by packing them with their\n * length (1 byte) in a single EVM word (32 bytes). Additionally, a\n * fallback mechanism can be used for every other case.\n *\n * Usage example:\n *\n * ```solidity\n * contract Named {\n * using ShortStrings for *;\n *\n * ShortString private immutable _name;\n * string private _nameFallback;\n *\n * constructor(string memory contractName) {\n * _name = contractName.toShortStringWithFallback(_nameFallback);\n * }\n *\n * function name() external view returns (string memory) {\n * return _name.toStringWithFallback(_nameFallback);\n * }\n * }\n * ```\n */\nlibrary ShortStrings {\n // Used as an identifier for strings longer than 31 bytes.\n bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;\n\n error StringTooLong(string str);\n error InvalidShortString();\n\n /**\n * @dev Encode a string of at most 31 chars into a `ShortString`.\n *\n * This will trigger a `StringTooLong` error is the input string is too long.\n */\n function toShortString(string memory str) internal pure returns (ShortString) {\n bytes memory bstr = bytes(str);\n if (bstr.length > 31) {\n revert StringTooLong(str);\n }\n return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));\n }\n\n /**\n * @dev Decode a `ShortString` back to a \"normal\" string.\n */\n function toString(ShortString sstr) internal pure returns (string memory) {\n uint256 len = byteLength(sstr);\n // using `new string(len)` would work locally but is not memory safe.\n string memory str = new string(32);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(str, len)\n mstore(add(str, 0x20), sstr)\n }\n return str;\n }\n\n /**\n * @dev Return the length of a `ShortString`.\n */\n function byteLength(ShortString sstr) internal pure returns (uint256) {\n uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;\n if (result > 31) {\n revert InvalidShortString();\n }\n return result;\n }\n\n /**\n * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.\n */\n function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {\n if (bytes(value).length < 32) {\n return toShortString(value);\n } else {\n StorageSlot.getStringSlot(store).value = value;\n return ShortString.wrap(_FALLBACK_SENTINEL);\n }\n }\n\n /**\n * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.\n */\n function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {\n if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {\n return toString(value);\n } else {\n return store;\n }\n }\n\n /**\n * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.\n *\n * WARNING: This will return the \"byte length\" of the string. This may not reflect the actual length in terms of\n * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.\n */\n function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {\n if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {\n return byteLength(value);\n } else {\n return bytes(store).length;\n }\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC5267.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267 {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/token/LivepeerTokenFaucet.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./ILivepeerToken.sol\";\n\nimport \"../zeppelin/Ownable.sol\";\n\n/**\n * @title Faucet for the Livepeer Token\n */\ncontract LivepeerTokenFaucet is Ownable {\n // Token\n ILivepeerToken public token;\n\n // Amount of token sent to sender for a request\n uint256 public requestAmount;\n\n // Amount of time a sender must wait between requests\n uint256 public requestWait;\n\n // sender => timestamp at which sender can make another request\n mapping(address => uint256) public nextValidRequest;\n\n // Whitelist addresses that can bypass faucet request rate limit\n mapping(address => bool) public isWhitelisted;\n\n // Checks if a request is valid (sender is whitelisted or has waited the rate limit time)\n modifier validRequest() {\n require(isWhitelisted[msg.sender] || block.timestamp >= nextValidRequest[msg.sender]);\n _;\n }\n\n event Request(address indexed to, uint256 amount);\n\n /**\n * @notice LivepeerTokenFacuet constructor\n * @param _token Address of LivepeerToken\n * @param _requestAmount Amount of token sent to sender for a request\n * @param _requestWait Amount of time a sender must wait between request (denominated in hours)\n */\n constructor(\n address _token,\n uint256 _requestAmount,\n uint256 _requestWait\n ) {\n token = ILivepeerToken(_token);\n requestAmount = _requestAmount;\n requestWait = _requestWait;\n }\n\n /**\n * @notice Add an address to the whitelist\n * @param _addr Address to be whitelisted\n */\n function addToWhitelist(address _addr) external onlyOwner {\n isWhitelisted[_addr] = true;\n }\n\n /**\n * @notice Remove an address from the whitelist\n * @param _addr Address to be removed from whitelist\n */\n function removeFromWhitelist(address _addr) external onlyOwner {\n isWhitelisted[_addr] = false;\n }\n\n /**\n * @notice Request an amount of token to be sent to sender\n */\n function request() external validRequest {\n if (!isWhitelisted[msg.sender]) {\n nextValidRequest[msg.sender] = block.timestamp + requestWait * 1 hours;\n }\n\n token.transfer(msg.sender, requestAmount);\n\n emit Request(msg.sender, requestAmount);\n }\n}\n" + }, + "contracts/Controller.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./IController.sol\";\nimport \"./IManager.sol\";\n\nimport \"./zeppelin/Pausable.sol\";\n\ncontract Controller is Pausable, IController {\n // Track information about a registered contract\n struct ContractInfo {\n address contractAddress; // Address of contract\n bytes20 gitCommitHash; // SHA1 hash of head Git commit during registration of this contract\n }\n\n // Track contract ids and contract info\n mapping(bytes32 => ContractInfo) private registry;\n\n constructor() {\n // Start system as paused\n paused = true;\n }\n\n /**\n * @notice Register contract id and mapped address\n * @param _id Contract id (keccak256 hash of contract name)\n * @param _contractAddress Contract address\n */\n function setContractInfo(\n bytes32 _id,\n address _contractAddress,\n bytes20 _gitCommitHash\n ) external override onlyOwner {\n registry[_id].contractAddress = _contractAddress;\n registry[_id].gitCommitHash = _gitCommitHash;\n\n emit SetContractInfo(_id, _contractAddress, _gitCommitHash);\n }\n\n /**\n * @notice Update contract's controller\n * @param _id Contract id (keccak256 hash of contract name)\n * @param _controller Controller address\n */\n function updateController(bytes32 _id, address _controller) external override onlyOwner {\n return IManager(registry[_id].contractAddress).setController(_controller);\n }\n\n /**\n * @notice Return contract info for a given contract id\n * @param _id Contract id (keccak256 hash of contract name)\n */\n function getContractInfo(bytes32 _id) public view returns (address, bytes20) {\n return (registry[_id].contractAddress, registry[_id].gitCommitHash);\n }\n\n /**\n * @notice Get contract address for an id\n * @param _id Contract id\n */\n function getContract(bytes32 _id) public view override returns (address) {\n return registry[_id].contractAddress;\n }\n}\n" + }, + "contracts/test/mocks/ManagerFixture.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../Manager.sol\";\n\ncontract ManagerFixture is Manager {\n constructor(address controller) Manager(controller) {}\n\n function checkSchrodingerCat() public view whenSystemPaused returns (string memory) {\n return \"alive\";\n }\n}\n" + }, + "contracts/snapshots/MerkleSnapshot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../zeppelin/MerkleProof.sol\";\nimport \"../Manager.sol\";\n\ncontract MerkleSnapshot is Manager {\n mapping(bytes32 => bytes32) public snapshot;\n\n constructor(address _controller) Manager(_controller) {}\n\n function setSnapshot(bytes32 _id, bytes32 _root) external onlyControllerOwner {\n snapshot[_id] = _root;\n }\n\n function verify(\n bytes32 _id,\n bytes32[] calldata _proof,\n bytes32 _leaf\n ) external view returns (bool) {\n return MerkleProof.verify(_proof, snapshot[_id], _leaf);\n }\n}\n" + }, + "contracts/zeppelin/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\n */\nlibrary MerkleProof {\n /**\n * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n * defined by `root`. For this, a `proof` must be provided, containing\n * sibling hashes on the branch from the leaf to the root of the tree. Each\n * pair of leaves and each pair of pre-images are assumed to be sorted.\n */\n function verify(\n bytes32[] memory proof,\n bytes32 root,\n bytes32 leaf\n ) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\n if (computedHash <= proofElement) {\n // Hash(current computed hash + current element of the proof)\n computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n } else {\n // Hash(current element of the proof + current computed hash)\n computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n }\n }\n\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "contracts/test/mocks/ManagerProxyTargetMockV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../ManagerProxyTarget.sol\";\n\ncontract ManagerProxyTargetMockV3 is ManagerProxyTarget {\n uint256 public initValue;\n uint8 public uint8Value;\n uint64 public uint64Value;\n uint256 public uint256Value;\n bytes32 public bytes32Value;\n address public addressValue;\n mapping(uint256 => uint256) public kvMap;\n\n constructor(address _controller) Manager(_controller) {}\n\n function setUint8(uint8 _value) external {\n uint8Value = _value;\n }\n\n function setUint64(uint64 _value) external {\n uint64Value = _value;\n }\n\n function setUint256(uint256 _value) external {\n uint256Value = _value;\n }\n\n function setBytes32(bytes32 _value) external {\n bytes32Value = _value;\n }\n\n function setAddress(address _value) external {\n addressValue = _value;\n }\n\n function setKv(uint256 _key, uint256 _value) external {\n kvMap[_key] = _value;\n }\n}\n" + }, + "contracts/test/mocks/ManagerProxyTargetMockV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../ManagerProxyTarget.sol\";\n\ncontract ManagerProxyTargetMockV2 is ManagerProxyTarget {\n uint256 public initValue;\n uint8 public uint8Value;\n uint64 public uint64Value;\n uint256 public uint256Value;\n bytes32 public bytes32Value;\n address public addressValue;\n\n constructor(address _controller) Manager(_controller) {}\n\n function setUint8(uint8 _value) external {\n uint8Value = _value + 5;\n }\n\n function setUint64(uint64 _value) external {\n uint64Value = _value + 5;\n }\n\n function setUint256(uint256 _value) external {\n uint256Value = _value + 5;\n }\n\n function setBytes32(bytes32 _value) external {\n bytes32Value = keccak256(abi.encodePacked(_value));\n }\n\n function setAddress(address _value) external {\n addressValue = _value; // to supress compilation warnings\n addressValue = address(0);\n }\n}\n" + }, + "contracts/test/mocks/ManagerProxyTargetMockV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../ManagerProxyTarget.sol\";\n\ncontract ManagerProxyTargetMockV1 is ManagerProxyTarget {\n uint256 public initValue;\n uint8 public uint8Value;\n uint64 public uint64Value;\n uint256 public uint256Value;\n bytes32 public bytes32Value;\n address public addressValue;\n string public stringValue;\n bytes public bytesValue;\n uint256 public tupleValue1;\n uint256 public tupleValue2;\n bytes32 public tupleValue3;\n\n constructor(address _controller) Manager(_controller) {}\n\n receive() external payable {}\n\n function setUint8(uint8 _value) external {\n uint8Value = _value;\n }\n\n function setUint64(uint64 _value) external {\n uint64Value = _value;\n }\n\n function setUint256(uint256 _value) external {\n uint256Value = _value;\n }\n\n function setBytes32(bytes32 _value) external {\n bytes32Value = _value;\n }\n\n function setAddress(address _value) external {\n addressValue = _value;\n }\n\n function setString(string calldata _value) external {\n stringValue = _value;\n }\n\n function setBytes(bytes calldata _value) external {\n bytesValue = _value;\n }\n\n function setTuple(\n uint256 _value1,\n uint256 _value2,\n bytes32 _value3\n ) external {\n tupleValue1 = _value1;\n tupleValue2 = _value2;\n tupleValue3 = _value3;\n }\n\n function getTuple()\n external\n view\n returns (\n uint256,\n uint256,\n bytes32\n )\n {\n return (tupleValue1, tupleValue2, tupleValue3);\n }\n}\n" + }, + "contracts/ServiceRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./ManagerProxyTarget.sol\";\n\n/**\n * @title ServiceRegistry\n * @notice Maintains a registry of service metadata associated with service provider addresses (transcoders/orchestrators)\n */\ncontract ServiceRegistry is ManagerProxyTarget {\n // Store service metadata\n struct Record {\n string serviceURI; // Service URI endpoint that can be used to send off-chain requests\n }\n\n // Track records for addresses\n mapping(address => Record) private records;\n\n // Event fired when a caller updates its service URI endpoint\n event ServiceURIUpdate(address indexed addr, string serviceURI);\n\n /**\n * @notice ServiceRegistry constructor. Only invokes constructor of base Manager contract with provided Controller address\n * @param _controller Address of a Controller that this contract will be registered with\n */\n constructor(address _controller) Manager(_controller) {}\n\n /**\n * @notice Stores service URI endpoint for the caller that can be used to send requests to the caller off-chain\n * @param _serviceURI Service URI endpoint for the caller\n */\n function setServiceURI(string calldata _serviceURI) external {\n records[msg.sender].serviceURI = _serviceURI;\n\n emit ServiceURIUpdate(msg.sender, _serviceURI);\n }\n\n /**\n * @notice Returns service URI endpoint stored for a given address\n * @param _addr Address for which a service URI endpoint is desired\n */\n function getServiceURI(address _addr) public view returns (string memory) {\n return records[_addr].serviceURI;\n }\n}\n" + }, + "contracts/ManagerProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./ManagerProxyTarget.sol\";\n\n/**\n * @title ManagerProxy\n * @notice A proxy contract that uses delegatecall to execute function calls on a target contract using its own storage context.\n The target contract is a Manager contract that is registered with the Controller.\n * @dev Both this proxy contract and its target contract MUST inherit from ManagerProxyTarget in order to guarantee\n that both contracts have the same storage layout. Differing storage layouts in a proxy contract and target contract can\n potentially break the delegate proxy upgradeability mechanism. Since this proxy contract inherits from ManagerProxyTarget which inherits\n from Manager, it implements the setController() function. The target contract will also implement setController() since it also inherits\n from ManagerProxyTarget. Thus, any transaction sent to the proxy that calls setController() will execute against the proxy instead\n of the target. As a result, developers should keep in mind that the proxy will always execute the same logic for setController() regardless\n of the setController() implementation on the target contract. Generally, developers should not add any additional functions to this proxy contract\n because any function implemented on the proxy will always be executed against the proxy and the call **will not** be forwarded to the target contract\n */\ncontract ManagerProxy is ManagerProxyTarget {\n /**\n * @notice ManagerProxy constructor. Invokes constructor of base Manager contract with provided Controller address.\n * Also, sets the contract ID of the target contract that function calls will be executed on.\n * @param _controller Address of Controller that this contract will be registered with\n * @param _targetContractId contract ID of the target contract\n */\n constructor(address _controller, bytes32 _targetContractId) Manager(_controller) {\n targetContractId = _targetContractId;\n }\n\n /**\n * @notice Fallback function that delegates calls to target contract when there is no msg.data\n */\n receive() external payable {\n _fallback();\n }\n\n /**\n * @notice Fallback function that delegates calls to target contract when there is msg.data\n */\n fallback() external payable {\n _fallback();\n }\n\n /**\n * @dev Uses delegatecall to execute function calls on this proxy contract's target contract using its own storage context.\n This fallback function will look up the address of the target contract using the Controller and the target contract ID.\n It will then use the calldata for a function call as the data payload for a delegatecall on the target contract. The return value\n of the executed function call will also be returned\n */\n function _fallback() private {\n address target = controller.getContract(targetContractId);\n require(target != address(0), \"target contract must be registered\");\n\n assembly {\n // Solidity keeps a free memory pointer at position 0x40 in memory\n let freeMemoryPtrPosition := 0x40\n // Load the free memory pointer\n let calldataMemoryOffset := mload(freeMemoryPtrPosition)\n // Update free memory pointer to after memory space we reserve for calldata\n mstore(freeMemoryPtrPosition, add(calldataMemoryOffset, calldatasize()))\n // Copy calldata (method signature and params of the call) to memory\n calldatacopy(calldataMemoryOffset, 0x0, calldatasize())\n\n // Call method on target contract using calldata which is loaded into memory\n let ret := delegatecall(gas(), target, calldataMemoryOffset, calldatasize(), 0, 0)\n\n // Load the free memory pointer\n let returndataMemoryOffset := mload(freeMemoryPtrPosition)\n // Update free memory pointer to after memory space we reserve for returndata\n mstore(freeMemoryPtrPosition, add(returndataMemoryOffset, returndatasize()))\n // Copy returndata (result of the method invoked by the delegatecall) to memory\n returndatacopy(returndataMemoryOffset, 0x0, returndatasize())\n\n switch ret\n case 0 {\n // Method call failed - revert\n // Return any error message stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\n revert(returndataMemoryOffset, returndatasize())\n }\n default {\n // Return result of method call stored in mem[returndataMemoryOffset..(returndataMemoryOffset + returndatasize)]\n return(returndataMemoryOffset, returndatasize())\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/cryptography/EIP712.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n// EIP-2612 is Final as of 2022-11-01. This file is deprecated.\n\nimport \"./ERC20Permit.sol\";\n" + }, + "contracts/token/LivepeerToken.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line\npragma solidity 0.8.9;\n\nimport { AccessControl } from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport { ERC20, ERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport { ERC20Burnable } from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n// Copy of https://github.com/livepeer/arbitrum-lpt-bridge/blob/main/contracts/L2/token/LivepeerToken.sol\n// Tests at https://github.com/livepeer/arbitrum-lpt-bridge/blob/main/test/unit/L2/livepeerToken.test.ts\ncontract LivepeerToken is AccessControl, ERC20Burnable, ERC20Permit {\n bytes32 private immutable MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 private immutable BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n event Mint(address indexed to, uint256 amount);\n event Burn(address indexed burner, uint256 amount);\n\n constructor() ERC20(\"Livepeer Token\", \"LPT\") ERC20Permit(\"Livepeer Token\") {\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @notice Function to mint tokens\n * @dev Only callable by addreses with MINTER_ROLE\n * @param _to The address that will receive the minted tokens.\n * @param _amount The amount of tokens to mint.\n */\n function mint(address _to, uint256 _amount) external onlyRole(MINTER_ROLE) {\n _mint(_to, _amount);\n emit Mint(_to, _amount);\n }\n\n /**\n * @notice Burns a specific amount of msg.sender's tokens\n * @dev Only callable by addresses with BURNER_ROLE\n * @param _amount The amount of tokens to be burned\n */\n function burn(uint256 _amount) public override onlyRole(BURNER_ROLE) {\n super.burn(_amount);\n emit Burn(msg.sender, _amount);\n }\n\n /**\n * @notice Burns a specific amount of an address' tokens\n * @dev Only callable by addresses with BURNER_ROLE. Requires the address to approve the caller to burn the amount\n * @param _from Address to burn tokens for\n * @param _amount The amount of tokens to be burned\n */\n function burnFrom(address _from, uint256 _amount) public override onlyRole(BURNER_ROLE) {\n super.burnFrom(_from, _amount);\n emit Burn(_from, _amount);\n }\n}\n" + }, + "contracts/rounds/AdjustableRoundsManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"./RoundsManager.sol\";\n\ncontract AdjustableRoundsManager is RoundsManager {\n uint256 public num;\n bytes32 public hash;\n\n constructor(address _controller) RoundsManager(_controller) {}\n\n function setBlockNum(uint256 _num) external {\n num = _num;\n }\n\n function setBlockHash(bytes32 _hash) external {\n hash = _hash;\n }\n\n function mineBlocks(uint256 _blocks) external {\n num += _blocks;\n }\n\n function blockNum() public view override returns (uint256) {\n return num;\n }\n\n function blockHash(uint256 _block) public view override returns (bytes32) {\n require(_block >= blockNum() - 256);\n\n return hash;\n }\n}\n" + }, + "contracts/test/mocks/GovenorInterfacesFixture.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts-upgradeable/governance/IGovernorUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/governance/extensions/IGovernorTimelockUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\n\n/**\n * @dev This is a helper contract to return the expected interface values that the LivepeerGovenor interface should\n * support. This only exists in Solidity since generating these interfaces in JS is kinda of a pain.\n */\ncontract GovernorInterfacesFixture {\n function TimelockUpgradeableInterface() external pure returns (bytes4) {\n return type(IGovernorTimelockUpgradeable).interfaceId;\n }\n\n /**\n * @dev ID calculation logic copied from {GovernorUpgradeable-supportsInterface}.\n */\n function GovernorInterfaces() external pure returns (bytes4[] memory) {\n IGovernorUpgradeable governor;\n // \n bytes4 governorCancelId = governor.cancel.selector ^ governor.proposalProposer.selector;\n\n bytes4 governorParamsId = governor.castVoteWithReasonAndParams.selector ^\n governor.castVoteWithReasonAndParamsBySig.selector ^\n governor.getVotesWithParams.selector;\n\n // The original interface id in v4.3.\n bytes4 governor43Id = type(IGovernorUpgradeable).interfaceId ^\n type(IERC6372Upgradeable).interfaceId ^\n governorCancelId ^\n governorParamsId;\n\n // An updated interface id in v4.6, with params added.\n bytes4 governor46Id = type(IGovernorUpgradeable).interfaceId ^\n type(IERC6372Upgradeable).interfaceId ^\n governorCancelId;\n\n // For the updated interface id in v4.9, we use governorCancelId directly.\n // \n\n // replace the interface checks with return the expected interface ids\n bytes4[] memory ids = new bytes4[](4);\n ids[0] = governor43Id;\n ids[1] = governor46Id;\n ids[2] = governorCancelId;\n ids[3] = type(IERC1155ReceiverUpgradeable).interfaceId;\n return ids;\n }\n}\n" + }, + "contracts/test/mocks/LivepeerGovernorUpgradeMock.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"../../treasury/LivepeerGovernor.sol\";\n\ncontract LivepeerGovernorUpgradeMock is LivepeerGovernor {\n uint256 public customField;\n\n constructor(address _controller) LivepeerGovernor(_controller) {}\n\n function setCustomField(uint256 _customField) external {\n customField = _customField;\n }\n}\n" + }, + "contracts/governance/Governor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.9;\n\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n/**\n * @title Governor\n * @dev The Governor holds the rights to stage and execute contract calls i.e. changing Livepeer protocol parameters.\n */\ncontract Governor {\n using SafeMath for uint256;\n\n address public owner;\n\n /// @dev mapping of updateHash (keccak256(update) => executeBlock (block.number + delay)\n mapping(bytes32 => uint256) public updates;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n event UpdateStaged(Update update, uint256 delay);\n\n event UpdateExecuted(Update update);\n\n event UpdateCancelled(Update update);\n\n struct Update {\n address[] target;\n uint256[] value;\n bytes[] data;\n uint256 nonce;\n }\n\n /// @notice Throws if called by any account other than the owner.\n modifier onlyOwner() {\n require(msg.sender == owner, \"unauthorized: msg.sender not owner\");\n _;\n }\n\n /// @notice Throws if called by any account other than this contract.\n /// @dev Forces the `stage/execute` path to be used to call functions with this modifier instead of directly.\n modifier onlyThis() {\n require(msg.sender == address(this), \"unauthorized: msg.sender not Governor\");\n _;\n }\n\n /// @dev The Ownable constructor sets the original `owner` of the contract to the sender account.\n constructor() {\n owner = msg.sender;\n emit OwnershipTransferred(address(0), msg.sender);\n }\n\n /// @notice Allows the current owner to transfer control of the contract to a newOwner.\n /// @dev Can only be called through stage/execute, will revert if the caller is not this contract's address.\n /// @param newOwner The address to transfer ownership to.\n function transferOwnership(address newOwner) public onlyThis {\n require(newOwner != address(0), \"newOwner is a null address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n /// @notice Stage a batch of updates to be executed.\n /// @dev Reverts if the 'msg.sender' is not the 'owner'\n /// @dev Reverts if an update is already staged\n /// @param _update Update to be staged.\n /// @param _delay (uint256) Delay (in number of blocks) for the update.\n function stage(Update memory _update, uint256 _delay) public onlyOwner {\n bytes32 updateHash = keccak256(abi.encode(_update));\n\n require(updates[updateHash] == 0, \"update already staged\");\n\n updates[updateHash] = block.number.add(_delay);\n\n emit UpdateStaged(_update, _delay);\n }\n\n /// @notice Execute a staged update.\n /// @dev Updates are authorized during staging.\n /// @dev Reverts if a transaction can not be executed.\n /// @param _update Update to be staged.\n function execute(Update memory _update) public payable {\n bytes32 updateHash = keccak256(abi.encode(_update));\n uint256 executeBlock = updates[updateHash];\n\n require(executeBlock != 0, \"update is not staged\");\n require(block.number >= executeBlock, \"delay for update not expired\");\n\n // prevent re-entry and replay\n delete updates[updateHash];\n for (uint256 i = 0; i < _update.target.length; i++) {\n /* solium-disable-next-line */\n (bool success, bytes memory returnData) = _update.target[i].call{ value: _update.value[i] }(\n _update.data[i]\n );\n require(success, string(returnData));\n }\n\n emit UpdateExecuted(_update);\n }\n\n /// @notice Cancel a staged update.\n /// @dev Reverts if an update does not exist.\n /// @dev Reverts if the 'msg.sender' is not the 'owner'\n /// @param _update Update to be cancelled.\n function cancel(Update memory _update) public onlyOwner {\n bytes32 updateHash = keccak256(abi.encode(_update));\n uint256 executeBlock = updates[updateHash];\n\n require(executeBlock != 0, \"update is not staged\");\n delete updates[updateHash];\n\n emit UpdateCancelled(_update);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file