├── StakingContract ├── Ownable.sol └── Rebase.sol ├── README.md └── DistributeContract └── Splitter.sol /StakingContract/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "./Context.sol"; 4 | 5 | /** 6 | * @dev Contract module which provides a basic access control mechanism, where 7 | * there is an account (`owner`) that can be granted exclusive access to 8 | * specific functions. 9 | * 10 | * By default, the owner account will be the one that deploys the contract. 11 | * This can later be changed with {transferOwnership}. 12 | * 13 | * This module is used through inheritance. It will make available the modifier 14 | * `onlyOwner`, which can be applied to your functions to restrict their use to 15 | * the owner. 16 | */ 17 | abstract contract Ownable is Context { 18 | address private _owner; 19 | 20 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 21 | 22 | /** 23 | * @dev Initializes the contract setting the deployer as the initial owner. 24 | */ 25 | constructor() { 26 | _transferOwnership(_msgSender()); 27 | } 28 | 29 | /** 30 | * @dev Returns the address of the current owner. 31 | */ 32 | function owner() public view virtual returns (address) { 33 | return _owner; 34 | } 35 | 36 | /** 37 | * @dev Throws if called by any account other than the owner. 38 | */ 39 | modifier onlyOwner() { 40 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 41 | _; 42 | } 43 | 44 | /** 45 | * @dev Leaves the contract completely without owner. Calls to {onlyOwner} 46 | * will fail. Any functions restricted by `onlyOwner` will still be usable 47 | * by the owner. 48 | * 49 | * NOTE: Renouncing ownership will leave the contract without an owner, thereby 50 | * removing any functionality that is only available to the owner. 51 | */ 52 | function renounceOwnership() public virtual onlyOwner { 53 | _transferOwnership(address(0)); 54 | } 55 | 56 | /** 57 | * @dev Transfers ownership of the contract to a `newOwner`. Can only be 58 | * called by the current owner. 59 | */ 60 | function transferOwnership(address newOwner) public virtual onlyOwner { 61 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 62 | _transferOwnership(newOwner); 63 | } 64 | 65 | /** 66 | * @dev Transfers ownership of the contract by changing the `_owner`. 67 | * 68 | * Internal function without access restriction. 69 | */ 70 | function _transferOwnership(address newOwner) internal virtual { 71 | address oldOwner = _owner; 72 | _owner = newOwner; 73 | emit OwnershipTransferred(oldOwner, newOwner); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Staking and Distribution Contracts 2 | 3 | This repository contains two core Solidity smart contracts: `Rebase.sol` (Staking Contract) and `Splitter.sol` (Distribution Contract), along with a helper contract `StakeTracker.sol`. These contracts work together to enable users to stake various ERC20 tokens (and ETH) and receive rewards distributed by authorized entities.. 4 | 5 | ## Mechanism Explanation 6 | 7 | ### 1. Rebase Contract (`Rebase.sol`) 8 | 9 | The `Rebase` contract serves as the primary staking hub. It allows users to stake ERC20 tokens or ETH, and in return, they receive a corresponding amount of "reTokens" (rebasing tokens). 10 | 11 | * **Staking Tokens:** Users can stake any ERC20 token or native ETH (which is converted to WETH internally). When tokens are staked, the `Rebase` contract interacts with a dynamically created `ReToken` contract specific to the staked token. This `ReToken` contract then mints new `reTokens` to the user, representing their staked position. 12 | * **Dynamic `ReToken` Creation:** For each unique token staked, the `Rebase` contract deploys a minimal proxy (`cloneDeterministic`) of the `ReToken` contract. This ensures that each staked token has its own dedicated `reToken` that tracks its rebasing logic. 13 | * **Application Integration:** The `Rebase` contract allows for integration with various "applications" (represented by smart contract addresses). When a user stakes, they specify an `app` address. The `Rebase` contract then calls the `onStake` function on the specified `app` contract, notifying it of the new stake. 14 | * **Unstaking Tokens:** Users can unstake their tokens, which involves burning the `reTokens` and transferring the original staked tokens back to the user. Similarly, the `onUnstake` function on the `app` contract is called. 15 | * **Restaking Tokens:** Users can transfer their staked position from one application to another without fully unstaking and restaking. 16 | 17 | ### 2. Splitter Contract (`Splitter.sol`) 18 | 19 | The `Splitter` contract is responsible for receiving reward tokens and distributing them proportionally to users who have staked through the `Rebase` contract and linked to this `Splitter` as their `app`. 20 | 21 | * **Reward Token:** The `Splitter` contract is initialized with a specific `rewardToken` (an ERC20 token) that it will distribute. 22 | * **Distributors:** Only authorized `distributors` (addresses added by the contract owner) can send `rewardToken` to the `Splitter` contract for distribution. 23 | * **`StakeTracker` Integration:** The `Splitter` contract uses a `StakeTracker` contract to keep track of user stakes and reward distributions over time. 24 | * When a `distributor` sends `rewardToken` via the `split` function, the `Splitter` records this reward in the `StakeTracker` by creating a "snapshot." This snapshot captures the total supply of staked tokens at that moment and the amount of reward distributed. 25 | * When users stake or unstake via the `Rebase` contract, the `Splitter` (as an `app` of `Rebase`) receives `onStake` and `onUnstake` calls, and updates the `StakeTracker` accordingly. 26 | * **Claiming Rewards:** Users can `claim` their accumulated rewards. The `claim` function calculates a user's share of rewards based on their proportional stake at each snapshot when rewards were distributed. It then transfers the `rewardToken` to the user. To prevent excessive gas usage, users can specify a `limit` on the number of snapshots considered in a single claim transaction. 27 | 28 | ### 3. StakeTracker Contract (`StakeTracker.sol`) 29 | 30 | The `StakeTracker` contract is a specialized ERC20Snapshot token that acts as a ledger for tracking user stakes and reward allocations. 31 | 32 | * **ERC20Snapshot:** It extends OpenZeppelin's `ERC20Snapshot`, allowing it to record balances and total supply at specific points in time (snapshots). 33 | * **Tracking Rewards:** It maps snapshot IDs to the `rewardQuantity` received by the `Splitter` at that snapshot. 34 | * **Calculating User Rewards:** The `getUserReward` function calculates a user's proportional share of rewards for a given snapshot by comparing their `balanceOfAt` (their stake at that snapshot) to the `totalSupplyAt` (total staked supply at that snapshot). 35 | 36 | ## Usage Instructions 37 | 38 | ### Deployment 39 | 40 | 1. **Deploy `Rebase.sol`:** Deploy the `Rebase` contract. Note the address of the deployed `Rebase` contract. 41 | * Example on BaseScan: [0x89fA20b30a88811FBB044821FEC130793185c60B](https://basescan.org/address/0x89fa20b30a88811fbb044821fec130793185c60b) 42 | 2. **Deploy `Splitter.sol`:** Deploy the `Splitter` contract, providing the `stakeToken` (the token users will stake) and `rewardToken` (the token that will be distributed as rewards) addresses as constructor arguments. 43 | * Example on BaseScan: [0x6bc86cb06db133e939cc9d3cd27b6b34772dd0cb](https://basescan.org/address/0x6bc86cb06db133e939cc9d3cd27b6b34772dd0cb) 44 | 45 | ### Staking Tokens (via `Rebase` contract) 46 | 47 | To stake ERC20 tokens: 48 | 49 | 1. Approve the `Rebase` contract to spend your ERC20 tokens: 50 | ```solidity 51 | IERC20(YOUR_TOKEN_ADDRESS).approve(REBASE_CONTRACT_ADDRESS, AMOUNT_TO_STAKE); 52 | ``` 53 | 2. Call the `stake` function on the `Rebase` contract: 54 | ```solidity 55 | Rebase.stake(YOUR_TOKEN_ADDRESS, AMOUNT_TO_STAKE, SPLITTER_CONTRACT_ADDRESS); 56 | ``` 57 | (Replace `YOUR_TOKEN_ADDRESS`, `AMOUNT_TO_STAKE`, and `SPLITTER_CONTRACT_ADDRESS` with actual values.) 58 | 59 | To stake ETH: 60 | 61 | 1. Call the `stakeETH` function on the `Rebase` contract, sending the desired ETH amount: 62 | ```solidity 63 | Rebase.stakeETH(SPLITTER_CONTRACT_ADDRESS) payable; // send value with the transaction 64 | ``` 65 | (Replace `SPLITTER_CONTRACT_ADDRESS` with the actual value.) 66 | 67 | ### Unstaking Tokens (via `Rebase` contract) 68 | 69 | To unstake ERC20 tokens: 70 | 71 | ```solidity 72 | Rebase.unstake(YOUR_TOKEN_ADDRESS, AMOUNT_TO_UNSTAKE, SPLITTER_CONTRACT_ADDRESS); 73 | ``` 74 | 75 | To unstake ETH: 76 | 77 | ```solidity 78 | Rebase.unstakeETH(AMOUNT_TO_UNSTAKE, SPLITTER_CONTRACT_ADDRESS); 79 | ``` 80 | 81 | ### Distributing Rewards (via `Splitter` contract) 82 | 83 | Only approved distributors can perform this action. 84 | 85 | 1. The owner of the `Splitter` contract must add your address as a distributor: 86 | ```solidity 87 | Splitter.addDistributor(YOUR_DISTRIBUTOR_ADDRESS); 88 | ``` 89 | 2. Approve the `Splitter` contract to spend the reward tokens from your distributor address: 90 | ```solidity 91 | IERC20(REWARD_TOKEN_ADDRESS).approve(SPLITTER_CONTRACT_ADDRESS, AMOUNT_OF_REWARD); 92 | ``` 93 | 3. Call the `split` function on the `Splitter` contract to distribute rewards: 94 | ```solidity 95 | Splitter.split(AMOUNT_OF_REWARD); 96 | ``` 97 | 98 | ### Claiming Rewards (via `Splitter` contract) 99 | 100 | Any user can claim their earned rewards. 101 | 102 | ```solidity 103 | Splitter.claim(YOUR_RECEIVING_ADDRESS, MAX_SNAPSHOTS_TO_PROCESS); 104 | ``` 105 | (Replace `YOUR_RECEIVING_ADDRESS` with the address where you want to receive the rewards, and `MAX_SNAPSHOTS_TO_PROCESS` with a reasonable number to avoid gas limits, e.g., 50 or 100.) 106 | 107 | You can check your unclaimed earnings before claiming: 108 | 109 | ```solidity 110 | Splitter.getUnclaimedEarnings(YOUR_ADDRESS, MAX_SNAPSHOTS_TO_PROCESS); 111 | ``` 112 | -------------------------------------------------------------------------------- /StakingContract/Rebase.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | * @dev Interface of the ERC20 standard as defined in the EIP. 5 | */ 6 | interface IERC20 { 7 | /** 8 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 9 | * another (`to`). 10 | * 11 | * Note that `value` may be zero. 12 | */ 13 | event Transfer(address indexed from, address indexed to, uint256 value); 14 | 15 | /** 16 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 17 | * a call to {approve}. `value` is the new allowance. 18 | */ 19 | event Approval(address indexed owner, address indexed spender, uint256 value); 20 | 21 | /** 22 | * @dev Returns the amount of tokens in existence. 23 | */ 24 | function totalSupply() external view returns (uint256); 25 | 26 | /** 27 | * @dev Returns the amount of tokens owned by `account`. 28 | */ 29 | function balanceOf(address account) external view returns (uint256); 30 | 31 | /** 32 | * @dev Moves `amount` tokens from the caller's account to `to`. 33 | * 34 | * Returns a boolean value indicating whether the operation succeeded. 35 | * 36 | * Emits a {Transfer} event. 37 | */ 38 | function transfer(address to, uint256 amount) external returns (bool); 39 | 40 | /** 41 | * @dev Returns the remaining number of tokens that `spender` will be 42 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 43 | * zero by default. 44 | * 45 | * This value changes when {approve} or {transferFrom} are called. 46 | */ 47 | function allowance(address owner, address spender) external view returns (uint256); 48 | 49 | /** 50 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 51 | * 52 | * Returns a boolean value indicating whether the operation succeeded. 53 | * 54 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 55 | * that someone may use both the old and the new allowance by unfortunate 56 | * transaction ordering. One possible solution to mitigate this race 57 | * condition is to first reduce the spender's allowance to 0 and set the 58 | * desired value afterwards: 59 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 60 | * 61 | * Emits an {Approval} event. 62 | */ 63 | function approve(address spender, uint256 amount) external returns (bool); 64 | 65 | /** 66 | * @dev Moves `amount` tokens from `from` to `to` using the 67 | * allowance mechanism. `amount` is then deducted from the caller's 68 | * allowance. 69 | * 70 | * Returns a boolean value indicating whether the operation succeeded. 71 | * 72 | * Emits a {Transfer} event. 73 | */ 74 | function transferFrom(address from, address to, uint256 amount) external returns (bool); 75 | } 76 | 77 | // File: @openzeppelin/contracts@4.9.5/token/ERC20/extensions/IERC20Metadata.sol 78 | 79 | 80 | // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) 81 | 82 | pragma solidity ^0.8.0; 83 | 84 | 85 | /** 86 | * @dev Interface for the optional metadata functions from the ERC20 standard. 87 | * 88 | * _Available since v4.1._ 89 | */ 90 | interface IERC20Metadata is IERC20 { 91 | /** 92 | * @dev Returns the name of the token. 93 | */ 94 | function name() external view returns (string memory); 95 | 96 | /** 97 | * @dev Returns the symbol of the token. 98 | */ 99 | function symbol() external view returns (string memory); 100 | 101 | /** 102 | * @dev Returns the decimals places of the token. 103 | */ 104 | function decimals() external view returns (uint8); 105 | } 106 | 107 | // File: @openzeppelin/contracts@4.9.5/utils/Context.sol 108 | 109 | 110 | // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) 111 | 112 | pragma solidity ^0.8.0; 113 | 114 | /** 115 | * @dev Provides information about the current execution context, including the 116 | * sender of the transaction and its data. While these are generally available 117 | * via msg.sender and msg.data, they should not be accessed in such a direct 118 | * manner, since when dealing with meta-transactions the account sending and 119 | * paying for execution may not be the actual sender (as far as an application 120 | * is concerned). 121 | * 122 | * This contract is only required for intermediate, library-like contracts. 123 | */ 124 | abstract contract Context { 125 | function _msgSender() internal view virtual returns (address) { 126 | return msg.sender; 127 | } 128 | 129 | function _msgData() internal view virtual returns (bytes calldata) { 130 | return msg.data; 131 | } 132 | 133 | function _contextSuffixLength() internal view virtual returns (uint256) { 134 | return 0; 135 | } 136 | } 137 | 138 | // File: @openzeppelin/contracts@4.9.5/token/ERC20/ERC20.sol 139 | 140 | 141 | // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) 142 | 143 | pragma solidity ^0.8.0; 144 | 145 | 146 | /** 147 | * @dev Implementation of the {IERC20} interface. 148 | * 149 | * This implementation is agnostic to the way tokens are created. This means 150 | * that a supply mechanism has to be added in a derived contract using {_mint}. 151 | * For a generic mechanism see {ERC20PresetMinterPauser}. 152 | * 153 | * TIP: For a detailed writeup see our guide 154 | * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How 155 | * to implement supply mechanisms]. 156 | * 157 | * The default value of {decimals} is 18. To change this, you should override 158 | * this function so it returns a different value. 159 | * 160 | * We have followed general OpenZeppelin Contracts guidelines: functions revert 161 | * instead returning `false` on failure. This behavior is nonetheless 162 | * conventional and does not conflict with the expectations of ERC20 163 | * applications. 164 | * 165 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 166 | * This allows applications to reconstruct the allowance for all accounts just 167 | * by listening to said events. Other implementations of the EIP may not emit 168 | * these events, as it isn't required by the specification. 169 | * 170 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 171 | * functions have been added to mitigate the well-known issues around setting 172 | * allowances. See {IERC20-approve}. 173 | */ 174 | contract ERC20 is Context, IERC20, IERC20Metadata { 175 | mapping(address => uint256) private _balances; 176 | 177 | mapping(address => mapping(address => uint256)) private _allowances; 178 | 179 | uint256 private _totalSupply; 180 | 181 | string private _name; 182 | string private _symbol; 183 | 184 | /** 185 | * @dev Sets the values for {name} and {symbol}. 186 | * 187 | * All two of these values are immutable: they can only be set once during 188 | * construction. 189 | */ 190 | constructor(string memory name_, string memory symbol_) { 191 | _name = name_; 192 | _symbol = symbol_; 193 | } 194 | 195 | /** 196 | * @dev Returns the name of the token. 197 | */ 198 | function name() public view virtual override returns (string memory) { 199 | return _name; 200 | } 201 | 202 | /** 203 | * @dev Returns the symbol of the token, usually a shorter version of the 204 | * name. 205 | */ 206 | function symbol() public view virtual override returns (string memory) { 207 | return _symbol; 208 | } 209 | 210 | /** 211 | * @dev Returns the number of decimals used to get its user representation. 212 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 213 | * be displayed to a user as `5.05` (`505 / 10 ** 2`). 214 | * 215 | * Tokens usually opt for a value of 18, imitating the relationship between 216 | * Ether and Wei. This is the default value returned by this function, unless 217 | * it's overridden. 218 | * 219 | * NOTE: This information is only used for _display_ purposes: it in 220 | * no way affects any of the arithmetic of the contract, including 221 | * {IERC20-balanceOf} and {IERC20-transfer}. 222 | */ 223 | function decimals() public view virtual override returns (uint8) { 224 | return 18; 225 | } 226 | 227 | /** 228 | * @dev See {IERC20-totalSupply}. 229 | */ 230 | function totalSupply() public view virtual override returns (uint256) { 231 | return _totalSupply; 232 | } 233 | 234 | /** 235 | * @dev See {IERC20-balanceOf}. 236 | */ 237 | function balanceOf(address account) public view virtual override returns (uint256) { 238 | return _balances[account]; 239 | } 240 | 241 | /** 242 | * @dev See {IERC20-transfer}. 243 | * 244 | * Requirements: 245 | * 246 | * - `to` cannot be the zero address. 247 | * - the caller must have a balance of at least `amount`. 248 | */ 249 | function transfer(address to, uint256 amount) public virtual override returns (bool) { 250 | address owner = _msgSender(); 251 | _transfer(owner, to, amount); 252 | return true; 253 | } 254 | 255 | /** 256 | * @dev See {IERC20-allowance}. 257 | */ 258 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 259 | return _allowances[owner][spender]; 260 | } 261 | 262 | /** 263 | * @dev See {IERC20-approve}. 264 | * 265 | * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on 266 | * `transferFrom`. This is semantically equivalent to an infinite approval. 267 | * 268 | * Requirements: 269 | * 270 | * - `spender` cannot be the zero address. 271 | */ 272 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 273 | address owner = _msgSender(); 274 | _approve(owner, spender, amount); 275 | return true; 276 | } 277 | 278 | /** 279 | * @dev See {IERC20-transferFrom}. 280 | * 281 | * Emits an {Approval} event indicating the updated allowance. This is not 282 | * required by the EIP. See the note at the beginning of {ERC20}. 283 | * 284 | * NOTE: Does not update the allowance if the current allowance 285 | * is the maximum `uint256`. 286 | * 287 | * Requirements: 288 | * 289 | * - `from` and `to` cannot be the zero address. 290 | * - `from` must have a balance of at least `amount`. 291 | * - the caller must have allowance for ``from``'s tokens of at least 292 | * `amount`. 293 | */ 294 | function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { 295 | address spender = _msgSender(); 296 | _spendAllowance(from, spender, amount); 297 | _transfer(from, to, amount); 298 | return true; 299 | } 300 | 301 | /** 302 | * @dev Atomically increases the allowance granted to `spender` by the caller. 303 | * 304 | * This is an alternative to {approve} that can be used as a mitigation for 305 | * problems described in {IERC20-approve}. 306 | * 307 | * Emits an {Approval} event indicating the updated allowance. 308 | * 309 | * Requirements: 310 | * 311 | * - `spender` cannot be the zero address. 312 | */ 313 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 314 | address owner = _msgSender(); 315 | _approve(owner, spender, allowance(owner, spender) + addedValue); 316 | return true; 317 | } 318 | 319 | /** 320 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 321 | * 322 | * This is an alternative to {approve} that can be used as a mitigation for 323 | * problems described in {IERC20-approve}. 324 | * 325 | * Emits an {Approval} event indicating the updated allowance. 326 | * 327 | * Requirements: 328 | * 329 | * - `spender` cannot be the zero address. 330 | * - `spender` must have allowance for the caller of at least 331 | * `subtractedValue`. 332 | */ 333 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 334 | address owner = _msgSender(); 335 | uint256 currentAllowance = allowance(owner, spender); 336 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 337 | unchecked { 338 | _approve(owner, spender, currentAllowance - subtractedValue); 339 | } 340 | 341 | return true; 342 | } 343 | 344 | /** 345 | * @dev Moves `amount` of tokens from `from` to `to`. 346 | * 347 | * This internal function is equivalent to {transfer}, and can be used to 348 | * e.g. implement automatic token fees, slashing mechanisms, etc. 349 | * 350 | * Emits a {Transfer} event. 351 | * 352 | * Requirements: 353 | * 354 | * - `from` cannot be the zero address. 355 | * - `to` cannot be the zero address. 356 | * - `from` must have a balance of at least `amount`. 357 | */ 358 | function _transfer(address from, address to, uint256 amount) internal virtual { 359 | require(from != address(0), "ERC20: transfer from the zero address"); 360 | require(to != address(0), "ERC20: transfer to the zero address"); 361 | 362 | _beforeTokenTransfer(from, to, amount); 363 | 364 | uint256 fromBalance = _balances[from]; 365 | require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); 366 | unchecked { 367 | _balances[from] = fromBalance - amount; 368 | // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by 369 | // decrementing then incrementing. 370 | _balances[to] += amount; 371 | } 372 | 373 | emit Transfer(from, to, amount); 374 | 375 | _afterTokenTransfer(from, to, amount); 376 | } 377 | 378 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 379 | * the total supply. 380 | * 381 | * Emits a {Transfer} event with `from` set to the zero address. 382 | * 383 | * Requirements: 384 | * 385 | * - `account` cannot be the zero address. 386 | */ 387 | function _mint(address account, uint256 amount) internal virtual { 388 | require(account != address(0), "ERC20: mint to the zero address"); 389 | 390 | _beforeTokenTransfer(address(0), account, amount); 391 | 392 | _totalSupply += amount; 393 | unchecked { 394 | // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. 395 | _balances[account] += amount; 396 | } 397 | emit Transfer(address(0), account, amount); 398 | 399 | _afterTokenTransfer(address(0), account, amount); 400 | } 401 | 402 | /** 403 | * @dev Destroys `amount` tokens from `account`, reducing the 404 | * total supply. 405 | * 406 | * Emits a {Transfer} event with `to` set to the zero address. 407 | * 408 | * Requirements: 409 | * 410 | * - `account` cannot be the zero address. 411 | * - `account` must have at least `amount` tokens. 412 | */ 413 | function _burn(address account, uint256 amount) internal virtual { 414 | require(account != address(0), "ERC20: burn from the zero address"); 415 | 416 | _beforeTokenTransfer(account, address(0), amount); 417 | 418 | uint256 accountBalance = _balances[account]; 419 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 420 | unchecked { 421 | _balances[account] = accountBalance - amount; 422 | // Overflow not possible: amount <= accountBalance <= totalSupply. 423 | _totalSupply -= amount; 424 | } 425 | 426 | emit Transfer(account, address(0), amount); 427 | 428 | _afterTokenTransfer(account, address(0), amount); 429 | } 430 | 431 | /** 432 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 433 | * 434 | * This internal function is equivalent to `approve`, and can be used to 435 | * e.g. set automatic allowances for certain subsystems, etc. 436 | * 437 | * Emits an {Approval} event. 438 | * 439 | * Requirements: 440 | * 441 | * - `owner` cannot be the zero address. 442 | * - `spender` cannot be the zero address. 443 | */ 444 | function _approve(address owner, address spender, uint256 amount) internal virtual { 445 | require(owner != address(0), "ERC20: approve from the zero address"); 446 | require(spender != address(0), "ERC20: approve to the zero address"); 447 | 448 | _allowances[owner][spender] = amount; 449 | emit Approval(owner, spender, amount); 450 | } 451 | 452 | /** 453 | * @dev Updates `owner` s allowance for `spender` based on spent `amount`. 454 | * 455 | * Does not update the allowance amount in case of infinite allowance. 456 | * Revert if not enough allowance is available. 457 | * 458 | * Might emit an {Approval} event. 459 | */ 460 | function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { 461 | uint256 currentAllowance = allowance(owner, spender); 462 | if (currentAllowance != type(uint256).max) { 463 | require(currentAllowance >= amount, "ERC20: insufficient allowance"); 464 | unchecked { 465 | _approve(owner, spender, currentAllowance - amount); 466 | } 467 | } 468 | } 469 | 470 | /** 471 | * @dev Hook that is called before any transfer of tokens. This includes 472 | * minting and burning. 473 | * 474 | * Calling conditions: 475 | * 476 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 477 | * will be transferred to `to`. 478 | * - when `from` is zero, `amount` tokens will be minted for `to`. 479 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 480 | * - `from` and `to` are never both zero. 481 | * 482 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 483 | */ 484 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 485 | 486 | /** 487 | * @dev Hook that is called after any transfer of tokens. This includes 488 | * minting and burning. 489 | * 490 | * Calling conditions: 491 | * 492 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 493 | * has been transferred to `to`. 494 | * - when `from` is zero, `amount` tokens have been minted for `to`. 495 | * - when `to` is zero, `amount` of ``from``'s tokens have been burned. 496 | * - `from` and `to` are never both zero. 497 | * 498 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 499 | */ 500 | function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} 501 | } 502 | 503 | // File: @openzeppelin/contracts@4.9.5/proxy/Clones.sol 504 | 505 | 506 | // OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol) 507 | 508 | pragma solidity ^0.8.0; 509 | 510 | /** 511 | * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for 512 | * deploying minimal proxy contracts, also known as "clones". 513 | * 514 | * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies 515 | * > a minimal bytecode implementation that delegates all calls to a known, fixed address. 516 | * 517 | * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` 518 | * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the 519 | * deterministic method. 520 | * 521 | * _Available since v3.4._ 522 | */ 523 | library Clones { 524 | /** 525 | * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. 526 | * 527 | * This function uses the create opcode, which should never revert. 528 | */ 529 | function clone(address implementation) internal returns (address instance) { 530 | /// @solidity memory-safe-assembly 531 | assembly { 532 | // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes 533 | // of the `implementation` address with the bytecode before the address. 534 | mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) 535 | // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. 536 | mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) 537 | instance := create(0, 0x09, 0x37) 538 | } 539 | require(instance != address(0), "ERC1167: create failed"); 540 | } 541 | 542 | /** 543 | * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. 544 | * 545 | * This function uses the create2 opcode and a `salt` to deterministically deploy 546 | * the clone. Using the same `implementation` and `salt` multiple time will revert, since 547 | * the clones cannot be deployed twice at the same address. 548 | */ 549 | function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { 550 | /// @solidity memory-safe-assembly 551 | assembly { 552 | // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes 553 | // of the `implementation` address with the bytecode before the address. 554 | mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) 555 | // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. 556 | mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) 557 | instance := create2(0, 0x09, 0x37, salt) 558 | } 559 | require(instance != address(0), "ERC1167: create2 failed"); 560 | } 561 | 562 | /** 563 | * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. 564 | */ 565 | function predictDeterministicAddress( 566 | address implementation, 567 | bytes32 salt, 568 | address deployer 569 | ) internal pure returns (address predicted) { 570 | /// @solidity memory-safe-assembly 571 | assembly { 572 | let ptr := mload(0x40) 573 | mstore(add(ptr, 0x38), deployer) 574 | mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) 575 | mstore(add(ptr, 0x14), implementation) 576 | mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) 577 | mstore(add(ptr, 0x58), salt) 578 | mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) 579 | predicted := keccak256(add(ptr, 0x43), 0x55) 580 | } 581 | } 582 | 583 | /** 584 | * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. 585 | */ 586 | function predictDeterministicAddress( 587 | address implementation, 588 | bytes32 salt 589 | ) internal view returns (address predicted) { 590 | return predictDeterministicAddress(implementation, salt, address(this)); 591 | } 592 | } 593 | 594 | // File: @openzeppelin/contracts@4.9.5/utils/math/SafeMath.sol 595 | 596 | 597 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) 598 | 599 | pragma solidity ^0.8.0; 600 | 601 | // CAUTION 602 | // This version of SafeMath should only be used with Solidity 0.8 or later, 603 | // because it relies on the compiler's built in overflow checks. 604 | 605 | /** 606 | * @dev Wrappers over Solidity's arithmetic operations. 607 | * 608 | * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler 609 | * now has built in overflow checking. 610 | */ 611 | library SafeMath { 612 | /** 613 | * @dev Returns the addition of two unsigned integers, with an overflow flag. 614 | * 615 | * _Available since v3.4._ 616 | */ 617 | function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 618 | unchecked { 619 | uint256 c = a + b; 620 | if (c < a) return (false, 0); 621 | return (true, c); 622 | } 623 | } 624 | 625 | /** 626 | * @dev Returns the subtraction of two unsigned integers, with an overflow flag. 627 | * 628 | * _Available since v3.4._ 629 | */ 630 | function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { 631 | unchecked { 632 | if (b > a) return (false, 0); 633 | return (true, a - b); 634 | } 635 | } 636 | 637 | /** 638 | * @dev Returns the multiplication of two unsigned integers, with an overflow flag. 639 | * 640 | * _Available since v3.4._ 641 | */ 642 | function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { 643 | unchecked { 644 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 645 | // benefit is lost if 'b' is also tested. 646 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 647 | if (a == 0) return (true, 0); 648 | uint256 c = a * b; 649 | if (c / a != b) return (false, 0); 650 | return (true, c); 651 | } 652 | } 653 | 654 | /** 655 | * @dev Returns the division of two unsigned integers, with a division by zero flag. 656 | * 657 | * _Available since v3.4._ 658 | */ 659 | function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { 660 | unchecked { 661 | if (b == 0) return (false, 0); 662 | return (true, a / b); 663 | } 664 | } 665 | 666 | /** 667 | * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. 668 | * 669 | * _Available since v3.4._ 670 | */ 671 | function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { 672 | unchecked { 673 | if (b == 0) return (false, 0); 674 | return (true, a % b); 675 | } 676 | } 677 | 678 | /** 679 | * @dev Returns the addition of two unsigned integers, reverting on 680 | * overflow. 681 | * 682 | * Counterpart to Solidity's `+` operator. 683 | * 684 | * Requirements: 685 | * 686 | * - Addition cannot overflow. 687 | */ 688 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 689 | return a + b; 690 | } 691 | 692 | /** 693 | * @dev Returns the subtraction of two unsigned integers, reverting on 694 | * overflow (when the result is negative). 695 | * 696 | * Counterpart to Solidity's `-` operator. 697 | * 698 | * Requirements: 699 | * 700 | * - Subtraction cannot overflow. 701 | */ 702 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 703 | return a - b; 704 | } 705 | 706 | /** 707 | * @dev Returns the multiplication of two unsigned integers, reverting on 708 | * overflow. 709 | * 710 | * Counterpart to Solidity's `*` operator. 711 | * 712 | * Requirements: 713 | * 714 | * - Multiplication cannot overflow. 715 | */ 716 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 717 | return a * b; 718 | } 719 | 720 | /** 721 | * @dev Returns the integer division of two unsigned integers, reverting on 722 | * division by zero. The result is rounded towards zero. 723 | * 724 | * Counterpart to Solidity's `/` operator. 725 | * 726 | * Requirements: 727 | * 728 | * - The divisor cannot be zero. 729 | */ 730 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 731 | return a / b; 732 | } 733 | 734 | /** 735 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 736 | * reverting when dividing by zero. 737 | * 738 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 739 | * opcode (which leaves remaining gas untouched) while Solidity uses an 740 | * invalid opcode to revert (consuming all remaining gas). 741 | * 742 | * Requirements: 743 | * 744 | * - The divisor cannot be zero. 745 | */ 746 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 747 | return a % b; 748 | } 749 | 750 | /** 751 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 752 | * overflow (when the result is negative). 753 | * 754 | * CAUTION: This function is deprecated because it requires allocating memory for the error 755 | * message unnecessarily. For custom revert reasons use {trySub}. 756 | * 757 | * Counterpart to Solidity's `-` operator. 758 | * 759 | * Requirements: 760 | * 761 | * - Subtraction cannot overflow. 762 | */ 763 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 764 | unchecked { 765 | require(b <= a, errorMessage); 766 | return a - b; 767 | } 768 | } 769 | 770 | /** 771 | * @dev Returns the integer division of two unsigned integers, reverting with custom message on 772 | * division by zero. The result is rounded towards zero. 773 | * 774 | * Counterpart to Solidity's `/` operator. Note: this function uses a 775 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 776 | * uses an invalid opcode to revert (consuming all remaining gas). 777 | * 778 | * Requirements: 779 | * 780 | * - The divisor cannot be zero. 781 | */ 782 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 783 | unchecked { 784 | require(b > 0, errorMessage); 785 | return a / b; 786 | } 787 | } 788 | 789 | /** 790 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 791 | * reverting with custom message when dividing by zero. 792 | * 793 | * CAUTION: This function is deprecated because it requires allocating memory for the error 794 | * message unnecessarily. For custom revert reasons use {tryMod}. 795 | * 796 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 797 | * opcode (which leaves remaining gas untouched) while Solidity uses an 798 | * invalid opcode to revert (consuming all remaining gas). 799 | * 800 | * Requirements: 801 | * 802 | * - The divisor cannot be zero. 803 | */ 804 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 805 | unchecked { 806 | require(b > 0, errorMessage); 807 | return a % b; 808 | } 809 | } 810 | } 811 | 812 | // File: @openzeppelin/contracts@4.9.5/utils/structs/EnumerableSet.sol 813 | 814 | 815 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) 816 | // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. 817 | 818 | pragma solidity ^0.8.0; 819 | 820 | /** 821 | * @dev Library for managing 822 | * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive 823 | * types. 824 | * 825 | * Sets have the following properties: 826 | * 827 | * - Elements are added, removed, and checked for existence in constant time 828 | * (O(1)). 829 | * - Elements are enumerated in O(n). No guarantees are made on the ordering. 830 | * 831 | * ```solidity 832 | * contract Example { 833 | * // Add the library methods 834 | * using EnumerableSet for EnumerableSet.AddressSet; 835 | * 836 | * // Declare a set state variable 837 | * EnumerableSet.AddressSet private mySet; 838 | * } 839 | * ``` 840 | * 841 | * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) 842 | * and `uint256` (`UintSet`) are supported. 843 | * 844 | * [WARNING] 845 | * ==== 846 | * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure 847 | * unusable. 848 | * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. 849 | * 850 | * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an 851 | * array of EnumerableSet. 852 | * ==== 853 | */ 854 | library EnumerableSet { 855 | // To implement this library for multiple types with as little code 856 | // repetition as possible, we write it in terms of a generic Set type with 857 | // bytes32 values. 858 | // The Set implementation uses private functions, and user-facing 859 | // implementations (such as AddressSet) are just wrappers around the 860 | // underlying Set. 861 | // This means that we can only create new EnumerableSets for types that fit 862 | // in bytes32. 863 | 864 | struct Set { 865 | // Storage of set values 866 | bytes32[] _values; 867 | // Position of the value in the `values` array, plus 1 because index 0 868 | // means a value is not in the set. 869 | mapping(bytes32 => uint256) _indexes; 870 | } 871 | 872 | /** 873 | * @dev Add a value to a set. O(1). 874 | * 875 | * Returns true if the value was added to the set, that is if it was not 876 | * already present. 877 | */ 878 | function _add(Set storage set, bytes32 value) private returns (bool) { 879 | if (!_contains(set, value)) { 880 | set._values.push(value); 881 | // The value is stored at length-1, but we add 1 to all indexes 882 | // and use 0 as a sentinel value 883 | set._indexes[value] = set._values.length; 884 | return true; 885 | } else { 886 | return false; 887 | } 888 | } 889 | 890 | /** 891 | * @dev Removes a value from a set. O(1). 892 | * 893 | * Returns true if the value was removed from the set, that is if it was 894 | * present. 895 | */ 896 | function _remove(Set storage set, bytes32 value) private returns (bool) { 897 | // We read and store the value's index to prevent multiple reads from the same storage slot 898 | uint256 valueIndex = set._indexes[value]; 899 | 900 | if (valueIndex != 0) { 901 | // Equivalent to contains(set, value) 902 | // To delete an element from the _values array in O(1), we swap the element to delete with the last one in 903 | // the array, and then remove the last element (sometimes called as 'swap and pop'). 904 | // This modifies the order of the array, as noted in {at}. 905 | 906 | uint256 toDeleteIndex = valueIndex - 1; 907 | uint256 lastIndex = set._values.length - 1; 908 | 909 | if (lastIndex != toDeleteIndex) { 910 | bytes32 lastValue = set._values[lastIndex]; 911 | 912 | // Move the last value to the index where the value to delete is 913 | set._values[toDeleteIndex] = lastValue; 914 | // Update the index for the moved value 915 | set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex 916 | } 917 | 918 | // Delete the slot where the moved value was stored 919 | set._values.pop(); 920 | 921 | // Delete the index for the deleted slot 922 | delete set._indexes[value]; 923 | 924 | return true; 925 | } else { 926 | return false; 927 | } 928 | } 929 | 930 | /** 931 | * @dev Returns true if the value is in the set. O(1). 932 | */ 933 | function _contains(Set storage set, bytes32 value) private view returns (bool) { 934 | return set._indexes[value] != 0; 935 | } 936 | 937 | /** 938 | * @dev Returns the number of values on the set. O(1). 939 | */ 940 | function _length(Set storage set) private view returns (uint256) { 941 | return set._values.length; 942 | } 943 | 944 | /** 945 | * @dev Returns the value stored at position `index` in the set. O(1). 946 | * 947 | * Note that there are no guarantees on the ordering of values inside the 948 | * array, and it may change when more values are added or removed. 949 | * 950 | * Requirements: 951 | * 952 | * - `index` must be strictly less than {length}. 953 | */ 954 | function _at(Set storage set, uint256 index) private view returns (bytes32) { 955 | return set._values[index]; 956 | } 957 | 958 | /** 959 | * @dev Return the entire set in an array 960 | * 961 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 962 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 963 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 964 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 965 | */ 966 | function _values(Set storage set) private view returns (bytes32[] memory) { 967 | return set._values; 968 | } 969 | 970 | // Bytes32Set 971 | 972 | struct Bytes32Set { 973 | Set _inner; 974 | } 975 | 976 | /** 977 | * @dev Add a value to a set. O(1). 978 | * 979 | * Returns true if the value was added to the set, that is if it was not 980 | * already present. 981 | */ 982 | function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { 983 | return _add(set._inner, value); 984 | } 985 | 986 | /** 987 | * @dev Removes a value from a set. O(1). 988 | * 989 | * Returns true if the value was removed from the set, that is if it was 990 | * present. 991 | */ 992 | function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { 993 | return _remove(set._inner, value); 994 | } 995 | 996 | /** 997 | * @dev Returns true if the value is in the set. O(1). 998 | */ 999 | function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { 1000 | return _contains(set._inner, value); 1001 | } 1002 | 1003 | /** 1004 | * @dev Returns the number of values in the set. O(1). 1005 | */ 1006 | function length(Bytes32Set storage set) internal view returns (uint256) { 1007 | return _length(set._inner); 1008 | } 1009 | 1010 | /** 1011 | * @dev Returns the value stored at position `index` in the set. O(1). 1012 | * 1013 | * Note that there are no guarantees on the ordering of values inside the 1014 | * array, and it may change when more values are added or removed. 1015 | * 1016 | * Requirements: 1017 | * 1018 | * - `index` must be strictly less than {length}. 1019 | */ 1020 | function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { 1021 | return _at(set._inner, index); 1022 | } 1023 | 1024 | /** 1025 | * @dev Return the entire set in an array 1026 | * 1027 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1028 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1029 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1030 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 1031 | */ 1032 | function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { 1033 | bytes32[] memory store = _values(set._inner); 1034 | bytes32[] memory result; 1035 | 1036 | /// @solidity memory-safe-assembly 1037 | assembly { 1038 | result := store 1039 | } 1040 | 1041 | return result; 1042 | } 1043 | 1044 | // AddressSet 1045 | 1046 | struct AddressSet { 1047 | Set _inner; 1048 | } 1049 | 1050 | /** 1051 | * @dev Add a value to a set. O(1). 1052 | * 1053 | * Returns true if the value was added to the set, that is if it was not 1054 | * already present. 1055 | */ 1056 | function add(AddressSet storage set, address value) internal returns (bool) { 1057 | return _add(set._inner, bytes32(uint256(uint160(value)))); 1058 | } 1059 | 1060 | /** 1061 | * @dev Removes a value from a set. O(1). 1062 | * 1063 | * Returns true if the value was removed from the set, that is if it was 1064 | * present. 1065 | */ 1066 | function remove(AddressSet storage set, address value) internal returns (bool) { 1067 | return _remove(set._inner, bytes32(uint256(uint160(value)))); 1068 | } 1069 | 1070 | /** 1071 | * @dev Returns true if the value is in the set. O(1). 1072 | */ 1073 | function contains(AddressSet storage set, address value) internal view returns (bool) { 1074 | return _contains(set._inner, bytes32(uint256(uint160(value)))); 1075 | } 1076 | 1077 | /** 1078 | * @dev Returns the number of values in the set. O(1). 1079 | */ 1080 | function length(AddressSet storage set) internal view returns (uint256) { 1081 | return _length(set._inner); 1082 | } 1083 | 1084 | /** 1085 | * @dev Returns the value stored at position `index` in the set. O(1). 1086 | * 1087 | * Note that there are no guarantees on the ordering of values inside the 1088 | * array, and it may change when more values are added or removed. 1089 | * 1090 | * Requirements: 1091 | * 1092 | * - `index` must be strictly less than {length}. 1093 | */ 1094 | function at(AddressSet storage set, uint256 index) internal view returns (address) { 1095 | return address(uint160(uint256(_at(set._inner, index)))); 1096 | } 1097 | 1098 | /** 1099 | * @dev Return the entire set in an array 1100 | * 1101 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1102 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1103 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1104 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 1105 | */ 1106 | function values(AddressSet storage set) internal view returns (address[] memory) { 1107 | bytes32[] memory store = _values(set._inner); 1108 | address[] memory result; 1109 | 1110 | /// @solidity memory-safe-assembly 1111 | assembly { 1112 | result := store 1113 | } 1114 | 1115 | return result; 1116 | } 1117 | 1118 | // UintSet 1119 | 1120 | struct UintSet { 1121 | Set _inner; 1122 | } 1123 | 1124 | /** 1125 | * @dev Add a value to a set. O(1). 1126 | * 1127 | * Returns true if the value was added to the set, that is if it was not 1128 | * already present. 1129 | */ 1130 | function add(UintSet storage set, uint256 value) internal returns (bool) { 1131 | return _add(set._inner, bytes32(value)); 1132 | } 1133 | 1134 | /** 1135 | * @dev Removes a value from a set. O(1). 1136 | * 1137 | * Returns true if the value was removed from the set, that is if it was 1138 | * present. 1139 | */ 1140 | function remove(UintSet storage set, uint256 value) internal returns (bool) { 1141 | return _remove(set._inner, bytes32(value)); 1142 | } 1143 | 1144 | /** 1145 | * @dev Returns true if the value is in the set. O(1). 1146 | */ 1147 | function contains(UintSet storage set, uint256 value) internal view returns (bool) { 1148 | return _contains(set._inner, bytes32(value)); 1149 | } 1150 | 1151 | /** 1152 | * @dev Returns the number of values in the set. O(1). 1153 | */ 1154 | function length(UintSet storage set) internal view returns (uint256) { 1155 | return _length(set._inner); 1156 | } 1157 | 1158 | /** 1159 | * @dev Returns the value stored at position `index` in the set. O(1). 1160 | * 1161 | * Note that there are no guarantees on the ordering of values inside the 1162 | * array, and it may change when more values are added or removed. 1163 | * 1164 | * Requirements: 1165 | * 1166 | * - `index` must be strictly less than {length}. 1167 | */ 1168 | function at(UintSet storage set, uint256 index) internal view returns (uint256) { 1169 | return uint256(_at(set._inner, index)); 1170 | } 1171 | 1172 | /** 1173 | * @dev Return the entire set in an array 1174 | * 1175 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1176 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1177 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1178 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 1179 | */ 1180 | function values(UintSet storage set) internal view returns (uint256[] memory) { 1181 | bytes32[] memory store = _values(set._inner); 1182 | uint256[] memory result; 1183 | 1184 | /// @solidity memory-safe-assembly 1185 | assembly { 1186 | result := store 1187 | } 1188 | 1189 | return result; 1190 | } 1191 | } 1192 | 1193 | // File: @openzeppelin/contracts@4.9.5/utils/structs/EnumerableMap.sol 1194 | 1195 | 1196 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableMap.sol) 1197 | // This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. 1198 | 1199 | pragma solidity ^0.8.0; 1200 | 1201 | 1202 | /** 1203 | * @dev Library for managing an enumerable variant of Solidity's 1204 | * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] 1205 | * type. 1206 | * 1207 | * Maps have the following properties: 1208 | * 1209 | * - Entries are added, removed, and checked for existence in constant time 1210 | * (O(1)). 1211 | * - Entries are enumerated in O(n). No guarantees are made on the ordering. 1212 | * 1213 | * ```solidity 1214 | * contract Example { 1215 | * // Add the library methods 1216 | * using EnumerableMap for EnumerableMap.UintToAddressMap; 1217 | * 1218 | * // Declare a set state variable 1219 | * EnumerableMap.UintToAddressMap private myMap; 1220 | * } 1221 | * ``` 1222 | * 1223 | * The following map types are supported: 1224 | * 1225 | * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 1226 | * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 1227 | * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 1228 | * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 1229 | * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 1230 | * 1231 | * [WARNING] 1232 | * ==== 1233 | * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure 1234 | * unusable. 1235 | * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. 1236 | * 1237 | * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an 1238 | * array of EnumerableMap. 1239 | * ==== 1240 | */ 1241 | library EnumerableMap { 1242 | using EnumerableSet for EnumerableSet.Bytes32Set; 1243 | 1244 | // To implement this library for multiple types with as little code 1245 | // repetition as possible, we write it in terms of a generic Map type with 1246 | // bytes32 keys and values. 1247 | // The Map implementation uses private functions, and user-facing 1248 | // implementations (such as Uint256ToAddressMap) are just wrappers around 1249 | // the underlying Map. 1250 | // This means that we can only create new EnumerableMaps for types that fit 1251 | // in bytes32. 1252 | 1253 | struct Bytes32ToBytes32Map { 1254 | // Storage of keys 1255 | EnumerableSet.Bytes32Set _keys; 1256 | mapping(bytes32 => bytes32) _values; 1257 | } 1258 | 1259 | /** 1260 | * @dev Adds a key-value pair to a map, or updates the value for an existing 1261 | * key. O(1). 1262 | * 1263 | * Returns true if the key was added to the map, that is if it was not 1264 | * already present. 1265 | */ 1266 | function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) { 1267 | map._values[key] = value; 1268 | return map._keys.add(key); 1269 | } 1270 | 1271 | /** 1272 | * @dev Removes a key-value pair from a map. O(1). 1273 | * 1274 | * Returns true if the key was removed from the map, that is if it was present. 1275 | */ 1276 | function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { 1277 | delete map._values[key]; 1278 | return map._keys.remove(key); 1279 | } 1280 | 1281 | /** 1282 | * @dev Returns true if the key is in the map. O(1). 1283 | */ 1284 | function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { 1285 | return map._keys.contains(key); 1286 | } 1287 | 1288 | /** 1289 | * @dev Returns the number of key-value pairs in the map. O(1). 1290 | */ 1291 | function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { 1292 | return map._keys.length(); 1293 | } 1294 | 1295 | /** 1296 | * @dev Returns the key-value pair stored at position `index` in the map. O(1). 1297 | * 1298 | * Note that there are no guarantees on the ordering of entries inside the 1299 | * array, and it may change when more entries are added or removed. 1300 | * 1301 | * Requirements: 1302 | * 1303 | * - `index` must be strictly less than {length}. 1304 | */ 1305 | function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { 1306 | bytes32 key = map._keys.at(index); 1307 | return (key, map._values[key]); 1308 | } 1309 | 1310 | /** 1311 | * @dev Tries to returns the value associated with `key`. O(1). 1312 | * Does not revert if `key` is not in the map. 1313 | */ 1314 | function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { 1315 | bytes32 value = map._values[key]; 1316 | if (value == bytes32(0)) { 1317 | return (contains(map, key), bytes32(0)); 1318 | } else { 1319 | return (true, value); 1320 | } 1321 | } 1322 | 1323 | /** 1324 | * @dev Returns the value associated with `key`. O(1). 1325 | * 1326 | * Requirements: 1327 | * 1328 | * - `key` must be in the map. 1329 | */ 1330 | function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { 1331 | bytes32 value = map._values[key]; 1332 | require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); 1333 | return value; 1334 | } 1335 | 1336 | /** 1337 | * @dev Same as {get}, with a custom error message when `key` is not in the map. 1338 | * 1339 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1340 | * message unnecessarily. For custom revert reasons use {tryGet}. 1341 | */ 1342 | function get( 1343 | Bytes32ToBytes32Map storage map, 1344 | bytes32 key, 1345 | string memory errorMessage 1346 | ) internal view returns (bytes32) { 1347 | bytes32 value = map._values[key]; 1348 | require(value != 0 || contains(map, key), errorMessage); 1349 | return value; 1350 | } 1351 | 1352 | /** 1353 | * @dev Return the an array containing all the keys 1354 | * 1355 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1356 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1357 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1358 | * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. 1359 | */ 1360 | function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { 1361 | return map._keys.values(); 1362 | } 1363 | 1364 | // UintToUintMap 1365 | 1366 | struct UintToUintMap { 1367 | Bytes32ToBytes32Map _inner; 1368 | } 1369 | 1370 | /** 1371 | * @dev Adds a key-value pair to a map, or updates the value for an existing 1372 | * key. O(1). 1373 | * 1374 | * Returns true if the key was added to the map, that is if it was not 1375 | * already present. 1376 | */ 1377 | function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) { 1378 | return set(map._inner, bytes32(key), bytes32(value)); 1379 | } 1380 | 1381 | /** 1382 | * @dev Removes a value from a map. O(1). 1383 | * 1384 | * Returns true if the key was removed from the map, that is if it was present. 1385 | */ 1386 | function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { 1387 | return remove(map._inner, bytes32(key)); 1388 | } 1389 | 1390 | /** 1391 | * @dev Returns true if the key is in the map. O(1). 1392 | */ 1393 | function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { 1394 | return contains(map._inner, bytes32(key)); 1395 | } 1396 | 1397 | /** 1398 | * @dev Returns the number of elements in the map. O(1). 1399 | */ 1400 | function length(UintToUintMap storage map) internal view returns (uint256) { 1401 | return length(map._inner); 1402 | } 1403 | 1404 | /** 1405 | * @dev Returns the element stored at position `index` in the map. O(1). 1406 | * Note that there are no guarantees on the ordering of values inside the 1407 | * array, and it may change when more values are added or removed. 1408 | * 1409 | * Requirements: 1410 | * 1411 | * - `index` must be strictly less than {length}. 1412 | */ 1413 | function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { 1414 | (bytes32 key, bytes32 value) = at(map._inner, index); 1415 | return (uint256(key), uint256(value)); 1416 | } 1417 | 1418 | /** 1419 | * @dev Tries to returns the value associated with `key`. O(1). 1420 | * Does not revert if `key` is not in the map. 1421 | */ 1422 | function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { 1423 | (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); 1424 | return (success, uint256(value)); 1425 | } 1426 | 1427 | /** 1428 | * @dev Returns the value associated with `key`. O(1). 1429 | * 1430 | * Requirements: 1431 | * 1432 | * - `key` must be in the map. 1433 | */ 1434 | function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { 1435 | return uint256(get(map._inner, bytes32(key))); 1436 | } 1437 | 1438 | /** 1439 | * @dev Same as {get}, with a custom error message when `key` is not in the map. 1440 | * 1441 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1442 | * message unnecessarily. For custom revert reasons use {tryGet}. 1443 | */ 1444 | function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) { 1445 | return uint256(get(map._inner, bytes32(key), errorMessage)); 1446 | } 1447 | 1448 | /** 1449 | * @dev Return the an array containing all the keys 1450 | * 1451 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1452 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1453 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1454 | * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. 1455 | */ 1456 | function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { 1457 | bytes32[] memory store = keys(map._inner); 1458 | uint256[] memory result; 1459 | 1460 | /// @solidity memory-safe-assembly 1461 | assembly { 1462 | result := store 1463 | } 1464 | 1465 | return result; 1466 | } 1467 | 1468 | // UintToAddressMap 1469 | 1470 | struct UintToAddressMap { 1471 | Bytes32ToBytes32Map _inner; 1472 | } 1473 | 1474 | /** 1475 | * @dev Adds a key-value pair to a map, or updates the value for an existing 1476 | * key. O(1). 1477 | * 1478 | * Returns true if the key was added to the map, that is if it was not 1479 | * already present. 1480 | */ 1481 | function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { 1482 | return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); 1483 | } 1484 | 1485 | /** 1486 | * @dev Removes a value from a map. O(1). 1487 | * 1488 | * Returns true if the key was removed from the map, that is if it was present. 1489 | */ 1490 | function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { 1491 | return remove(map._inner, bytes32(key)); 1492 | } 1493 | 1494 | /** 1495 | * @dev Returns true if the key is in the map. O(1). 1496 | */ 1497 | function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { 1498 | return contains(map._inner, bytes32(key)); 1499 | } 1500 | 1501 | /** 1502 | * @dev Returns the number of elements in the map. O(1). 1503 | */ 1504 | function length(UintToAddressMap storage map) internal view returns (uint256) { 1505 | return length(map._inner); 1506 | } 1507 | 1508 | /** 1509 | * @dev Returns the element stored at position `index` in the map. O(1). 1510 | * Note that there are no guarantees on the ordering of values inside the 1511 | * array, and it may change when more values are added or removed. 1512 | * 1513 | * Requirements: 1514 | * 1515 | * - `index` must be strictly less than {length}. 1516 | */ 1517 | function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { 1518 | (bytes32 key, bytes32 value) = at(map._inner, index); 1519 | return (uint256(key), address(uint160(uint256(value)))); 1520 | } 1521 | 1522 | /** 1523 | * @dev Tries to returns the value associated with `key`. O(1). 1524 | * Does not revert if `key` is not in the map. 1525 | */ 1526 | function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { 1527 | (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); 1528 | return (success, address(uint160(uint256(value)))); 1529 | } 1530 | 1531 | /** 1532 | * @dev Returns the value associated with `key`. O(1). 1533 | * 1534 | * Requirements: 1535 | * 1536 | * - `key` must be in the map. 1537 | */ 1538 | function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { 1539 | return address(uint160(uint256(get(map._inner, bytes32(key))))); 1540 | } 1541 | 1542 | /** 1543 | * @dev Same as {get}, with a custom error message when `key` is not in the map. 1544 | * 1545 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1546 | * message unnecessarily. For custom revert reasons use {tryGet}. 1547 | */ 1548 | function get( 1549 | UintToAddressMap storage map, 1550 | uint256 key, 1551 | string memory errorMessage 1552 | ) internal view returns (address) { 1553 | return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); 1554 | } 1555 | 1556 | /** 1557 | * @dev Return the an array containing all the keys 1558 | * 1559 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1560 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1561 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1562 | * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. 1563 | */ 1564 | function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { 1565 | bytes32[] memory store = keys(map._inner); 1566 | uint256[] memory result; 1567 | 1568 | /// @solidity memory-safe-assembly 1569 | assembly { 1570 | result := store 1571 | } 1572 | 1573 | return result; 1574 | } 1575 | 1576 | // AddressToUintMap 1577 | 1578 | struct AddressToUintMap { 1579 | Bytes32ToBytes32Map _inner; 1580 | } 1581 | 1582 | /** 1583 | * @dev Adds a key-value pair to a map, or updates the value for an existing 1584 | * key. O(1). 1585 | * 1586 | * Returns true if the key was added to the map, that is if it was not 1587 | * already present. 1588 | */ 1589 | function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) { 1590 | return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); 1591 | } 1592 | 1593 | /** 1594 | * @dev Removes a value from a map. O(1). 1595 | * 1596 | * Returns true if the key was removed from the map, that is if it was present. 1597 | */ 1598 | function remove(AddressToUintMap storage map, address key) internal returns (bool) { 1599 | return remove(map._inner, bytes32(uint256(uint160(key)))); 1600 | } 1601 | 1602 | /** 1603 | * @dev Returns true if the key is in the map. O(1). 1604 | */ 1605 | function contains(AddressToUintMap storage map, address key) internal view returns (bool) { 1606 | return contains(map._inner, bytes32(uint256(uint160(key)))); 1607 | } 1608 | 1609 | /** 1610 | * @dev Returns the number of elements in the map. O(1). 1611 | */ 1612 | function length(AddressToUintMap storage map) internal view returns (uint256) { 1613 | return length(map._inner); 1614 | } 1615 | 1616 | /** 1617 | * @dev Returns the element stored at position `index` in the map. O(1). 1618 | * Note that there are no guarantees on the ordering of values inside the 1619 | * array, and it may change when more values are added or removed. 1620 | * 1621 | * Requirements: 1622 | * 1623 | * - `index` must be strictly less than {length}. 1624 | */ 1625 | function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { 1626 | (bytes32 key, bytes32 value) = at(map._inner, index); 1627 | return (address(uint160(uint256(key))), uint256(value)); 1628 | } 1629 | 1630 | /** 1631 | * @dev Tries to returns the value associated with `key`. O(1). 1632 | * Does not revert if `key` is not in the map. 1633 | */ 1634 | function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { 1635 | (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); 1636 | return (success, uint256(value)); 1637 | } 1638 | 1639 | /** 1640 | * @dev Returns the value associated with `key`. O(1). 1641 | * 1642 | * Requirements: 1643 | * 1644 | * - `key` must be in the map. 1645 | */ 1646 | function get(AddressToUintMap storage map, address key) internal view returns (uint256) { 1647 | return uint256(get(map._inner, bytes32(uint256(uint160(key))))); 1648 | } 1649 | 1650 | /** 1651 | * @dev Same as {get}, with a custom error message when `key` is not in the map. 1652 | * 1653 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1654 | * message unnecessarily. For custom revert reasons use {tryGet}. 1655 | */ 1656 | function get( 1657 | AddressToUintMap storage map, 1658 | address key, 1659 | string memory errorMessage 1660 | ) internal view returns (uint256) { 1661 | return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); 1662 | } 1663 | 1664 | /** 1665 | * @dev Return the an array containing all the keys 1666 | * 1667 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1668 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1669 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1670 | * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. 1671 | */ 1672 | function keys(AddressToUintMap storage map) internal view returns (address[] memory) { 1673 | bytes32[] memory store = keys(map._inner); 1674 | address[] memory result; 1675 | 1676 | /// @solidity memory-safe-assembly 1677 | assembly { 1678 | result := store 1679 | } 1680 | 1681 | return result; 1682 | } 1683 | 1684 | // Bytes32ToUintMap 1685 | 1686 | struct Bytes32ToUintMap { 1687 | Bytes32ToBytes32Map _inner; 1688 | } 1689 | 1690 | /** 1691 | * @dev Adds a key-value pair to a map, or updates the value for an existing 1692 | * key. O(1). 1693 | * 1694 | * Returns true if the key was added to the map, that is if it was not 1695 | * already present. 1696 | */ 1697 | function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) { 1698 | return set(map._inner, key, bytes32(value)); 1699 | } 1700 | 1701 | /** 1702 | * @dev Removes a value from a map. O(1). 1703 | * 1704 | * Returns true if the key was removed from the map, that is if it was present. 1705 | */ 1706 | function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { 1707 | return remove(map._inner, key); 1708 | } 1709 | 1710 | /** 1711 | * @dev Returns true if the key is in the map. O(1). 1712 | */ 1713 | function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { 1714 | return contains(map._inner, key); 1715 | } 1716 | 1717 | /** 1718 | * @dev Returns the number of elements in the map. O(1). 1719 | */ 1720 | function length(Bytes32ToUintMap storage map) internal view returns (uint256) { 1721 | return length(map._inner); 1722 | } 1723 | 1724 | /** 1725 | * @dev Returns the element stored at position `index` in the map. O(1). 1726 | * Note that there are no guarantees on the ordering of values inside the 1727 | * array, and it may change when more values are added or removed. 1728 | * 1729 | * Requirements: 1730 | * 1731 | * - `index` must be strictly less than {length}. 1732 | */ 1733 | function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { 1734 | (bytes32 key, bytes32 value) = at(map._inner, index); 1735 | return (key, uint256(value)); 1736 | } 1737 | 1738 | /** 1739 | * @dev Tries to returns the value associated with `key`. O(1). 1740 | * Does not revert if `key` is not in the map. 1741 | */ 1742 | function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { 1743 | (bool success, bytes32 value) = tryGet(map._inner, key); 1744 | return (success, uint256(value)); 1745 | } 1746 | 1747 | /** 1748 | * @dev Returns the value associated with `key`. O(1). 1749 | * 1750 | * Requirements: 1751 | * 1752 | * - `key` must be in the map. 1753 | */ 1754 | function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { 1755 | return uint256(get(map._inner, key)); 1756 | } 1757 | 1758 | /** 1759 | * @dev Same as {get}, with a custom error message when `key` is not in the map. 1760 | * 1761 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1762 | * message unnecessarily. For custom revert reasons use {tryGet}. 1763 | */ 1764 | function get( 1765 | Bytes32ToUintMap storage map, 1766 | bytes32 key, 1767 | string memory errorMessage 1768 | ) internal view returns (uint256) { 1769 | return uint256(get(map._inner, key, errorMessage)); 1770 | } 1771 | 1772 | /** 1773 | * @dev Return the an array containing all the keys 1774 | * 1775 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 1776 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 1777 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 1778 | * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. 1779 | */ 1780 | function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { 1781 | bytes32[] memory store = keys(map._inner); 1782 | bytes32[] memory result; 1783 | 1784 | /// @solidity memory-safe-assembly 1785 | assembly { 1786 | result := store 1787 | } 1788 | 1789 | return result; 1790 | } 1791 | } 1792 | 1793 | // File: @openzeppelin/contracts@4.9.5/security/ReentrancyGuard.sol 1794 | 1795 | 1796 | // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) 1797 | 1798 | pragma solidity ^0.8.0; 1799 | 1800 | /** 1801 | * @dev Contract module that helps prevent reentrant calls to a function. 1802 | * 1803 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 1804 | * available, which can be applied to functions to make sure there are no nested 1805 | * (reentrant) calls to them. 1806 | * 1807 | * Note that because there is a single `nonReentrant` guard, functions marked as 1808 | * `nonReentrant` may not call one another. This can be worked around by making 1809 | * those functions `private`, and then adding `external` `nonReentrant` entry 1810 | * points to them. 1811 | * 1812 | * TIP: If you would like to learn more about reentrancy and alternative ways 1813 | * to protect against it, check out our blog post 1814 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 1815 | */ 1816 | abstract contract ReentrancyGuard { 1817 | // Booleans are more expensive than uint256 or any type that takes up a full 1818 | // word because each write operation emits an extra SLOAD to first read the 1819 | // slot's contents, replace the bits taken up by the boolean, and then write 1820 | // back. This is the compiler's defense against contract upgrades and 1821 | // pointer aliasing, and it cannot be disabled. 1822 | 1823 | // The values being non-zero value makes deployment a bit more expensive, 1824 | // but in exchange the refund on every call to nonReentrant will be lower in 1825 | // amount. Since refunds are capped to a percentage of the total 1826 | // transaction's gas, it is best to keep them low in cases like this one, to 1827 | // increase the likelihood of the full refund coming into effect. 1828 | uint256 private constant _NOT_ENTERED = 1; 1829 | uint256 private constant _ENTERED = 2; 1830 | 1831 | uint256 private _status; 1832 | 1833 | constructor() { 1834 | _status = _NOT_ENTERED; 1835 | } 1836 | 1837 | /** 1838 | * @dev Prevents a contract from calling itself, directly or indirectly. 1839 | * Calling a `nonReentrant` function from another `nonReentrant` 1840 | * function is not supported. It is possible to prevent this from happening 1841 | * by making the `nonReentrant` function external, and making it call a 1842 | * `private` function that does the actual work. 1843 | */ 1844 | modifier nonReentrant() { 1845 | _nonReentrantBefore(); 1846 | _; 1847 | _nonReentrantAfter(); 1848 | } 1849 | 1850 | function _nonReentrantBefore() private { 1851 | // On the first call to nonReentrant, _status will be _NOT_ENTERED 1852 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 1853 | 1854 | // Any calls to nonReentrant after this point will fail 1855 | _status = _ENTERED; 1856 | } 1857 | 1858 | function _nonReentrantAfter() private { 1859 | // By storing the original value once again, a refund is triggered (see 1860 | // https://eips.ethereum.org/EIPS/eip-2200) 1861 | _status = _NOT_ENTERED; 1862 | } 1863 | 1864 | /** 1865 | * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a 1866 | * `nonReentrant` function in the call stack. 1867 | */ 1868 | function _reentrancyGuardEntered() internal view returns (bool) { 1869 | return _status == _ENTERED; 1870 | } 1871 | } 1872 | 1873 | // File: ReToken.sol 1874 | 1875 | 1876 | pragma solidity ^0.8.20; 1877 | 1878 | 1879 | contract ReToken is ERC20 { 1880 | address private _deployer; 1881 | address private _token; 1882 | 1883 | modifier onlyDeployer { 1884 | require(msg.sender == _deployer, "Only callable by deployer"); 1885 | _; 1886 | } 1887 | 1888 | constructor() ERC20("", "") { 1889 | _deployer = msg.sender; 1890 | } 1891 | 1892 | function initialize(address token) external { 1893 | require(_deployer == address(0), "Initialized"); 1894 | _deployer = msg.sender; 1895 | _token = token; 1896 | } 1897 | 1898 | function name() public view override returns (string memory) { 1899 | return string.concat("Rebase ", ERC20(_token).name()); 1900 | } 1901 | 1902 | function symbol() public view override returns (string memory) { 1903 | return string.concat("re", ERC20(_token).symbol()); 1904 | } 1905 | 1906 | function decimals() public view override returns (uint8) { 1907 | return ERC20(_token).decimals(); 1908 | } 1909 | 1910 | function mint(address to, uint tokens) external onlyDeployer { 1911 | _mint(to, tokens); 1912 | } 1913 | 1914 | function burn(address from, uint tokens) external onlyDeployer { 1915 | _burn(from, tokens); 1916 | } 1917 | } 1918 | 1919 | // File: Rebase.sol 1920 | 1921 | 1922 | pragma solidity ^0.8.20; 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | interface Rebased { 1932 | function onStake(address user, address token, uint quantity) external; 1933 | function onUnstake(address user, address token, uint quantity) external; 1934 | } 1935 | 1936 | interface WETH { 1937 | function deposit() external payable; 1938 | function withdraw(uint amount) external; 1939 | } 1940 | 1941 | contract Rebase is ReentrancyGuard { 1942 | using EnumerableSet for EnumerableSet.AddressSet; 1943 | using EnumerableMap for EnumerableMap.AddressToUintMap; 1944 | using EnumerableMap for EnumerableMap.UintToAddressMap; 1945 | using SafeMath for uint256; 1946 | 1947 | struct User { 1948 | EnumerableSet.AddressSet apps; 1949 | mapping(address => EnumerableMap.AddressToUintMap) appTokenStakes; 1950 | } 1951 | 1952 | EnumerableMap.UintToAddressMap private _tokenReToken; 1953 | mapping(address => User) private _users; 1954 | mapping(address => EnumerableMap.AddressToUintMap) private _appTokenStakes; 1955 | mapping(address => EnumerableSet.AddressSet) private _appUsers; 1956 | 1957 | address private constant _WETH = 0x4200000000000000000000000000000000000006; 1958 | address private immutable _clonableToken; 1959 | 1960 | uint public constant UNRESTAKE_GAS_LIMIT = 1000000; 1961 | 1962 | uint256 public newVariable; 1963 | 1964 | event Stake ( 1965 | address indexed user, 1966 | address indexed app, 1967 | address indexed token, 1968 | uint quantity 1969 | ); 1970 | 1971 | event Unstake ( 1972 | address indexed user, 1973 | address indexed app, 1974 | address indexed token, 1975 | uint quantity, 1976 | bool forced 1977 | ); 1978 | 1979 | event RebaseInitialized(address indexed deployer); 1980 | 1981 | constructor() { 1982 | _clonableToken = address(new ReToken()); 1983 | } 1984 | 1985 | receive() external payable { } 1986 | 1987 | function stake(address token, uint quantity, address app) external nonReentrant { 1988 | require(ERC20(token).transferFrom(msg.sender, address(this), quantity), "Unable to transfer token"); 1989 | _getReToken(token).mint(msg.sender, quantity); 1990 | _stake(app, token, quantity); 1991 | } 1992 | 1993 | function stakeETH(address app) external payable nonReentrant { 1994 | WETH(_WETH).deposit{value: msg.value}(); 1995 | _getReToken(_WETH).mint(msg.sender, msg.value); 1996 | _stake(app, _WETH, msg.value); 1997 | } 1998 | 1999 | function unstake(address token, uint quantity, address app) external nonReentrant { 2000 | _unstake(app, token, quantity); 2001 | _getReToken(token).burn(msg.sender, quantity); 2002 | require(ERC20(token).transfer(msg.sender, quantity), "Unable to transfer token"); 2003 | } 2004 | 2005 | function unstakeETH(uint quantity, address app) external nonReentrant { 2006 | _unstake(app, _WETH, quantity); 2007 | _getReToken(_WETH).burn(msg.sender, quantity); 2008 | WETH(_WETH).withdraw(quantity); 2009 | (bool transferred,) = msg.sender.call{value: quantity}(""); 2010 | require(transferred, "Transfer failed"); 2011 | } 2012 | 2013 | function restake(address token, uint quantity, address fromApp, address toApp) external nonReentrant { 2014 | _unstake(fromApp, token, quantity); 2015 | _stake(toApp, token, quantity); 2016 | } 2017 | 2018 | function _stake(address app, address token, uint quantity) internal { 2019 | User storage user = _users[msg.sender]; 2020 | (,uint userStake) = user.appTokenStakes[app].tryGet(token); 2021 | (,uint appStake) = _appTokenStakes[app].tryGet(token); 2022 | 2023 | require(quantity > 0, "Invalid token quantity"); 2024 | 2025 | user.apps.add(app); 2026 | user.appTokenStakes[app].set(token, userStake.add(quantity)); 2027 | _appTokenStakes[app].set(token, appStake.add(quantity)); 2028 | _appUsers[app].add(msg.sender); 2029 | 2030 | Rebased(app).onStake(msg.sender, token, quantity); 2031 | 2032 | emit Stake(msg.sender, app, token, quantity); 2033 | } 2034 | 2035 | function _unstake(address app, address token, uint quantity) internal { 2036 | User storage user = _users[msg.sender]; 2037 | (,uint userStake) = user.appTokenStakes[app].tryGet(token); 2038 | (,uint appStake) = _appTokenStakes[app].tryGet(token); 2039 | 2040 | require(quantity > 0 && quantity <= userStake, "Invalid token quantity"); 2041 | 2042 | if (userStake == quantity) { 2043 | user.appTokenStakes[app].remove(token); 2044 | if (user.appTokenStakes[app].length() == 0) { 2045 | user.apps.remove(app); 2046 | _appUsers[app].remove(msg.sender); 2047 | } 2048 | } else { 2049 | user.appTokenStakes[app].set(token, userStake.sub(quantity)); 2050 | } 2051 | _appTokenStakes[app].set(token, appStake.sub(quantity)); 2052 | 2053 | bool forced = false; 2054 | try Rebased(app).onUnstake{gas: UNRESTAKE_GAS_LIMIT}(msg.sender, token, quantity) { } 2055 | catch { forced = true; } 2056 | 2057 | emit Unstake(msg.sender, app, token, quantity, forced); 2058 | } 2059 | 2060 | function _getReToken(address token) internal returns (ReToken) { 2061 | uint tokenId = _tokenToId(token); 2062 | (bool exists, address reToken) = _tokenReToken.tryGet(tokenId); 2063 | if (!exists) { 2064 | reToken = Clones.cloneDeterministic(_clonableToken, bytes32(tokenId)); 2065 | ReToken(reToken).initialize(token); 2066 | _tokenReToken.set(tokenId, reToken); 2067 | } 2068 | return ReToken(reToken); 2069 | } 2070 | 2071 | function _tokenToId(address token) internal pure returns (uint) { 2072 | return uint(uint160(token)); 2073 | } 2074 | 2075 | function getUserApps(address user) external view returns (address[] memory) { 2076 | return _users[user].apps.values(); 2077 | } 2078 | 2079 | function getUserAppAt(address user, uint index) external view returns (address) { 2080 | return _users[user].apps.at(index); 2081 | } 2082 | 2083 | function getNumUserApps(address user) external view returns (uint) { 2084 | return _users[user].apps.length(); 2085 | } 2086 | 2087 | function getAppUsers(address app) external view returns (address[] memory) { 2088 | return _appUsers[app].values(); 2089 | } 2090 | 2091 | function getAppUserAt(address app, uint index) external view returns (address) { 2092 | return _appUsers[app].at(index); 2093 | } 2094 | 2095 | function getNumAppUsers(address app) external view returns (uint) { 2096 | return _appUsers[app].length(); 2097 | } 2098 | 2099 | function getAppStake(address app, address token) external view returns (uint) { 2100 | (,uint appStake) = _appTokenStakes[app].tryGet(token); 2101 | return appStake; 2102 | } 2103 | 2104 | function getAppStakes(address app) external view returns (address[] memory, uint[] memory) { 2105 | EnumerableMap.AddressToUintMap storage appStakes = _appTokenStakes[app]; 2106 | address[] memory tokens = appStakes.keys(); 2107 | uint[] memory stakes = new uint[](tokens.length); 2108 | for (uint i = 0; i < tokens.length; i++) { 2109 | stakes[i] = appStakes.get(tokens[i]); 2110 | } 2111 | return (tokens, stakes); 2112 | } 2113 | 2114 | function getAppStakeAt(address app, uint index) external view returns (address, uint) { 2115 | return _appTokenStakes[app].at(index); 2116 | } 2117 | 2118 | function getNumAppStakes(address app) external view returns (uint) { 2119 | return _appTokenStakes[app].length(); 2120 | } 2121 | 2122 | function getUserAppStake(address user, address app, address token) external view returns (uint) { 2123 | (,uint userStake) = _users[user].appTokenStakes[app].tryGet(token); 2124 | return userStake; 2125 | } 2126 | 2127 | function getUserAppStakes(address user, address app) external view returns (address[] memory, uint[] memory) { 2128 | EnumerableMap.AddressToUintMap storage userStakes = _users[user].appTokenStakes[app]; 2129 | address[] memory tokens = userStakes.keys(); 2130 | uint[] memory stakes = new uint[](tokens.length); 2131 | for (uint i = 0; i < tokens.length; i++) { 2132 | stakes[i] = userStakes.get(tokens[i]); 2133 | } 2134 | return (tokens, stakes); 2135 | } 2136 | 2137 | function getUserAppStakeAt(address user, address app, uint index) external view returns (address, uint) { 2138 | return _users[user].appTokenStakes[app].at(index); 2139 | } 2140 | 2141 | function getNumUserAppStakes(address user, address app) external view returns (uint) { 2142 | return _users[user].appTokenStakes[app].length(); 2143 | } 2144 | 2145 | function getReToken(address token) external view returns (address) { 2146 | return _tokenReToken.get(_tokenToId(token)); 2147 | } 2148 | } -------------------------------------------------------------------------------- /DistributeContract/Splitter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | * @dev Interface of the ERC20 standard as defined in the EIP. 5 | */ 6 | interface IERC20 { 7 | /** 8 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 9 | * another (`to`). 10 | * 11 | * Note that `value` may be zero. 12 | */ 13 | event Transfer(address indexed from, address indexed to, uint256 value); 14 | 15 | /** 16 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 17 | * a call to {approve}. `value` is the new allowance. 18 | */ 19 | event Approval(address indexed owner, address indexed spender, uint256 value); 20 | 21 | /** 22 | * @dev Returns the amount of tokens in existence. 23 | */ 24 | function totalSupply() external view returns (uint256); 25 | 26 | /** 27 | * @dev Returns the amount of tokens owned by `account`. 28 | */ 29 | function balanceOf(address account) external view returns (uint256); 30 | 31 | /** 32 | * @dev Moves `amount` tokens from the caller's account to `to`. 33 | * 34 | * Returns a boolean value indicating whether the operation succeeded. 35 | * 36 | * Emits a {Transfer} event. 37 | */ 38 | function transfer(address to, uint256 amount) external returns (bool); 39 | 40 | /** 41 | * @dev Returns the remaining number of tokens that `spender` will be 42 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 43 | * zero by default. 44 | * 45 | * This value changes when {approve} or {transferFrom} are called. 46 | */ 47 | function allowance(address owner, address spender) external view returns (uint256); 48 | 49 | /** 50 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 51 | * 52 | * Returns a boolean value indicating whether the operation succeeded. 53 | * 54 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 55 | * that someone may use both the old and the new allowance by unfortunate 56 | * transaction ordering. One possible solution to mitigate this race 57 | * condition is to first reduce the spender's allowance to 0 and set the 58 | * desired value afterwards: 59 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 60 | * 61 | * Emits an {Approval} event. 62 | */ 63 | function approve(address spender, uint256 amount) external returns (bool); 64 | 65 | /** 66 | * @dev Moves `amount` tokens from `from` to `to` using the 67 | * allowance mechanism. `amount` is then deducted from the caller's 68 | * allowance. 69 | * 70 | * Returns a boolean value indicating whether the operation succeeded. 71 | * 72 | * Emits a {Transfer} event. 73 | */ 74 | function transferFrom(address from, address to, uint256 amount) external returns (bool); 75 | } 76 | 77 | // File: @openzeppelin/contracts@4.9.5/utils/Context.sol 78 | 79 | 80 | // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) 81 | 82 | pragma solidity ^0.8.0; 83 | 84 | /** 85 | * @dev Provides information about the current execution context, including the 86 | * sender of the transaction and its data. While these are generally available 87 | * via msg.sender and msg.data, they should not be accessed in such a direct 88 | * manner, since when dealing with meta-transactions the account sending and 89 | * paying for execution may not be the actual sender (as far as an application 90 | * is concerned). 91 | * 92 | * This contract is only required for intermediate, library-like contracts. 93 | */ 94 | abstract contract Context { 95 | function _msgSender() internal view virtual returns (address) { 96 | return msg.sender; 97 | } 98 | 99 | function _msgData() internal view virtual returns (bytes calldata) { 100 | return msg.data; 101 | } 102 | 103 | function _contextSuffixLength() internal view virtual returns (uint256) { 104 | return 0; 105 | } 106 | } 107 | 108 | // File: @openzeppelin/contracts@4.9.5/access/Ownable.sol 109 | 110 | 111 | // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) 112 | 113 | pragma solidity ^0.8.0; 114 | 115 | 116 | /** 117 | * @dev Contract module which provides a basic access control mechanism, where 118 | * there is an account (an owner) that can be granted exclusive access to 119 | * specific functions. 120 | * 121 | * By default, the owner account will be the one that deploys the contract. This 122 | * can later be changed with {transferOwnership}. 123 | * 124 | * This module is used through inheritance. It will make available the modifier 125 | * `onlyOwner`, which can be applied to your functions to restrict their use to 126 | * the owner. 127 | */ 128 | abstract contract Ownable is Context { 129 | address private _owner; 130 | 131 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 132 | 133 | /** 134 | * @dev Initializes the contract setting the deployer as the initial owner. 135 | */ 136 | constructor() { 137 | _transferOwnership(_msgSender()); 138 | } 139 | 140 | /** 141 | * @dev Throws if called by any account other than the owner. 142 | */ 143 | modifier onlyOwner() { 144 | _checkOwner(); 145 | _; 146 | } 147 | 148 | /** 149 | * @dev Returns the address of the current owner. 150 | */ 151 | function owner() public view virtual returns (address) { 152 | return _owner; 153 | } 154 | 155 | /** 156 | * @dev Throws if the sender is not the owner. 157 | */ 158 | function _checkOwner() internal view virtual { 159 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 160 | } 161 | 162 | /** 163 | * @dev Leaves the contract without owner. It will not be possible to call 164 | * `onlyOwner` functions. Can only be called by the current owner. 165 | * 166 | * NOTE: Renouncing ownership will leave the contract without an owner, 167 | * thereby disabling any functionality that is only available to the owner. 168 | */ 169 | function renounceOwnership() public virtual onlyOwner { 170 | _transferOwnership(address(0)); 171 | } 172 | 173 | /** 174 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 175 | * Can only be called by the current owner. 176 | */ 177 | function transferOwnership(address newOwner) public virtual onlyOwner { 178 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 179 | _transferOwnership(newOwner); 180 | } 181 | 182 | /** 183 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 184 | * Internal function without access restriction. 185 | */ 186 | function _transferOwnership(address newOwner) internal virtual { 187 | address oldOwner = _owner; 188 | _owner = newOwner; 189 | emit OwnershipTransferred(oldOwner, newOwner); 190 | } 191 | } 192 | 193 | // File: @openzeppelin/contracts@4.9.5/utils/structs/EnumerableSet.sol 194 | 195 | 196 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) 197 | // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. 198 | 199 | pragma solidity ^0.8.0; 200 | 201 | /** 202 | * @dev Library for managing 203 | * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive 204 | * types. 205 | * 206 | * Sets have the following properties: 207 | * 208 | * - Elements are added, removed, and checked for existence in constant time 209 | * (O(1)). 210 | * - Elements are enumerated in O(n). No guarantees are made on the ordering. 211 | * 212 | * ```solidity 213 | * contract Example { 214 | * // Add the library methods 215 | * using EnumerableSet for EnumerableSet.AddressSet; 216 | * 217 | * // Declare a set state variable 218 | * EnumerableSet.AddressSet private mySet; 219 | * } 220 | * ``` 221 | * 222 | * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) 223 | * and `uint256` (`UintSet`) are supported. 224 | * 225 | * [WARNING] 226 | * ==== 227 | * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure 228 | * unusable. 229 | * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. 230 | * 231 | * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an 232 | * array of EnumerableSet. 233 | * ==== 234 | */ 235 | library EnumerableSet { 236 | // To implement this library for multiple types with as little code 237 | // repetition as possible, we write it in terms of a generic Set type with 238 | // bytes32 values. 239 | // The Set implementation uses private functions, and user-facing 240 | // implementations (such as AddressSet) are just wrappers around the 241 | // underlying Set. 242 | // This means that we can only create new EnumerableSets for types that fit 243 | // in bytes32. 244 | 245 | struct Set { 246 | // Storage of set values 247 | bytes32[] _values; 248 | // Position of the value in the `values` array, plus 1 because index 0 249 | // means a value is not in the set. 250 | mapping(bytes32 => uint256) _indexes; 251 | } 252 | 253 | /** 254 | * @dev Add a value to a set. O(1). 255 | * 256 | * Returns true if the value was added to the set, that is if it was not 257 | * already present. 258 | */ 259 | function _add(Set storage set, bytes32 value) private returns (bool) { 260 | if (!_contains(set, value)) { 261 | set._values.push(value); 262 | // The value is stored at length-1, but we add 1 to all indexes 263 | // and use 0 as a sentinel value 264 | set._indexes[value] = set._values.length; 265 | return true; 266 | } else { 267 | return false; 268 | } 269 | } 270 | 271 | /** 272 | * @dev Removes a value from a set. O(1). 273 | * 274 | * Returns true if the value was removed from the set, that is if it was 275 | * present. 276 | */ 277 | function _remove(Set storage set, bytes32 value) private returns (bool) { 278 | // We read and store the value's index to prevent multiple reads from the same storage slot 279 | uint256 valueIndex = set._indexes[value]; 280 | 281 | if (valueIndex != 0) { 282 | // Equivalent to contains(set, value) 283 | // To delete an element from the _values array in O(1), we swap the element to delete with the last one in 284 | // the array, and then remove the last element (sometimes called as 'swap and pop'). 285 | // This modifies the order of the array, as noted in {at}. 286 | 287 | uint256 toDeleteIndex = valueIndex - 1; 288 | uint256 lastIndex = set._values.length - 1; 289 | 290 | if (lastIndex != toDeleteIndex) { 291 | bytes32 lastValue = set._values[lastIndex]; 292 | 293 | // Move the last value to the index where the value to delete is 294 | set._values[toDeleteIndex] = lastValue; 295 | // Update the index for the moved value 296 | set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex 297 | } 298 | 299 | // Delete the slot where the moved value was stored 300 | set._values.pop(); 301 | 302 | // Delete the index for the deleted slot 303 | delete set._indexes[value]; 304 | 305 | return true; 306 | } else { 307 | return false; 308 | } 309 | } 310 | 311 | /** 312 | * @dev Returns true if the value is in the set. O(1). 313 | */ 314 | function _contains(Set storage set, bytes32 value) private view returns (bool) { 315 | return set._indexes[value] != 0; 316 | } 317 | 318 | /** 319 | * @dev Returns the number of values on the set. O(1). 320 | */ 321 | function _length(Set storage set) private view returns (uint256) { 322 | return set._values.length; 323 | } 324 | 325 | /** 326 | * @dev Returns the value stored at position `index` in the set. O(1). 327 | * 328 | * Note that there are no guarantees on the ordering of values inside the 329 | * array, and it may change when more values are added or removed. 330 | * 331 | * Requirements: 332 | * 333 | * - `index` must be strictly less than {length}. 334 | */ 335 | function _at(Set storage set, uint256 index) private view returns (bytes32) { 336 | return set._values[index]; 337 | } 338 | 339 | /** 340 | * @dev Return the entire set in an array 341 | * 342 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 343 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 344 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 345 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 346 | */ 347 | function _values(Set storage set) private view returns (bytes32[] memory) { 348 | return set._values; 349 | } 350 | 351 | // Bytes32Set 352 | 353 | struct Bytes32Set { 354 | Set _inner; 355 | } 356 | 357 | /** 358 | * @dev Add a value to a set. O(1). 359 | * 360 | * Returns true if the value was added to the set, that is if it was not 361 | * already present. 362 | */ 363 | function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { 364 | return _add(set._inner, value); 365 | } 366 | 367 | /** 368 | * @dev Removes a value from a set. O(1). 369 | * 370 | * Returns true if the value was removed from the set, that is if it was 371 | * present. 372 | */ 373 | function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { 374 | return _remove(set._inner, value); 375 | } 376 | 377 | /** 378 | * @dev Returns true if the value is in the set. O(1). 379 | */ 380 | function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { 381 | return _contains(set._inner, value); 382 | } 383 | 384 | /** 385 | * @dev Returns the number of values in the set. O(1). 386 | */ 387 | function length(Bytes32Set storage set) internal view returns (uint256) { 388 | return _length(set._inner); 389 | } 390 | 391 | /** 392 | * @dev Returns the value stored at position `index` in the set. O(1). 393 | * 394 | * Note that there are no guarantees on the ordering of values inside the 395 | * array, and it may change when more values are added or removed. 396 | * 397 | * Requirements: 398 | * 399 | * - `index` must be strictly less than {length}. 400 | */ 401 | function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { 402 | return _at(set._inner, index); 403 | } 404 | 405 | /** 406 | * @dev Return the entire set in an array 407 | * 408 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 409 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 410 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 411 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 412 | */ 413 | function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { 414 | bytes32[] memory store = _values(set._inner); 415 | bytes32[] memory result; 416 | 417 | /// @solidity memory-safe-assembly 418 | assembly { 419 | result := store 420 | } 421 | 422 | return result; 423 | } 424 | 425 | // AddressSet 426 | 427 | struct AddressSet { 428 | Set _inner; 429 | } 430 | 431 | /** 432 | * @dev Add a value to a set. O(1). 433 | * 434 | * Returns true if the value was added to the set, that is if it was not 435 | * already present. 436 | */ 437 | function add(AddressSet storage set, address value) internal returns (bool) { 438 | return _add(set._inner, bytes32(uint256(uint160(value)))); 439 | } 440 | 441 | /** 442 | * @dev Removes a value from a set. O(1). 443 | * 444 | * Returns true if the value was removed from the set, that is if it was 445 | * present. 446 | */ 447 | function remove(AddressSet storage set, address value) internal returns (bool) { 448 | return _remove(set._inner, bytes32(uint256(uint160(value)))); 449 | } 450 | 451 | /** 452 | * @dev Returns true if the value is in the set. O(1). 453 | */ 454 | function contains(AddressSet storage set, address value) internal view returns (bool) { 455 | return _contains(set._inner, bytes32(uint256(uint160(value)))); 456 | } 457 | 458 | /** 459 | * @dev Returns the number of values in the set. O(1). 460 | */ 461 | function length(AddressSet storage set) internal view returns (uint256) { 462 | return _length(set._inner); 463 | } 464 | 465 | /** 466 | * @dev Returns the value stored at position `index` in the set. O(1). 467 | * 468 | * Note that there are no guarantees on the ordering of values inside the 469 | * array, and it may change when more values are added or removed. 470 | * 471 | * Requirements: 472 | * 473 | * - `index` must be strictly less than {length}. 474 | */ 475 | function at(AddressSet storage set, uint256 index) internal view returns (address) { 476 | return address(uint160(uint256(_at(set._inner, index)))); 477 | } 478 | 479 | /** 480 | * @dev Return the entire set in an array 481 | * 482 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 483 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 484 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 485 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 486 | */ 487 | function values(AddressSet storage set) internal view returns (address[] memory) { 488 | bytes32[] memory store = _values(set._inner); 489 | address[] memory result; 490 | 491 | /// @solidity memory-safe-assembly 492 | assembly { 493 | result := store 494 | } 495 | 496 | return result; 497 | } 498 | 499 | // UintSet 500 | 501 | struct UintSet { 502 | Set _inner; 503 | } 504 | 505 | /** 506 | * @dev Add a value to a set. O(1). 507 | * 508 | * Returns true if the value was added to the set, that is if it was not 509 | * already present. 510 | */ 511 | function add(UintSet storage set, uint256 value) internal returns (bool) { 512 | return _add(set._inner, bytes32(value)); 513 | } 514 | 515 | /** 516 | * @dev Removes a value from a set. O(1). 517 | * 518 | * Returns true if the value was removed from the set, that is if it was 519 | * present. 520 | */ 521 | function remove(UintSet storage set, uint256 value) internal returns (bool) { 522 | return _remove(set._inner, bytes32(value)); 523 | } 524 | 525 | /** 526 | * @dev Returns true if the value is in the set. O(1). 527 | */ 528 | function contains(UintSet storage set, uint256 value) internal view returns (bool) { 529 | return _contains(set._inner, bytes32(value)); 530 | } 531 | 532 | /** 533 | * @dev Returns the number of values in the set. O(1). 534 | */ 535 | function length(UintSet storage set) internal view returns (uint256) { 536 | return _length(set._inner); 537 | } 538 | 539 | /** 540 | * @dev Returns the value stored at position `index` in the set. O(1). 541 | * 542 | * Note that there are no guarantees on the ordering of values inside the 543 | * array, and it may change when more values are added or removed. 544 | * 545 | * Requirements: 546 | * 547 | * - `index` must be strictly less than {length}. 548 | */ 549 | function at(UintSet storage set, uint256 index) internal view returns (uint256) { 550 | return uint256(_at(set._inner, index)); 551 | } 552 | 553 | /** 554 | * @dev Return the entire set in an array 555 | * 556 | * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 557 | * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 558 | * this function has an unbounded cost, and using it as part of a state-changing function may render the function 559 | * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 560 | */ 561 | function values(UintSet storage set) internal view returns (uint256[] memory) { 562 | bytes32[] memory store = _values(set._inner); 563 | uint256[] memory result; 564 | 565 | /// @solidity memory-safe-assembly 566 | assembly { 567 | result := store 568 | } 569 | 570 | return result; 571 | } 572 | } 573 | 574 | // File: JOBS/IRebased.sol 575 | 576 | 577 | pragma solidity ^0.8.20; 578 | 579 | interface Rebased { 580 | function onStake(address user, address token, uint quantity) external; 581 | function onUnstake(address user, address token, uint quantity) external; 582 | } 583 | // File: @openzeppelin/contracts@4.9.5/token/ERC20/extensions/IERC20Metadata.sol 584 | 585 | 586 | // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) 587 | 588 | pragma solidity ^0.8.0; 589 | 590 | 591 | /** 592 | * @dev Interface for the optional metadata functions from the ERC20 standard. 593 | * 594 | * _Available since v4.1._ 595 | */ 596 | interface IERC20Metadata is IERC20 { 597 | /** 598 | * @dev Returns the name of the token. 599 | */ 600 | function name() external view returns (string memory); 601 | 602 | /** 603 | * @dev Returns the symbol of the token. 604 | */ 605 | function symbol() external view returns (string memory); 606 | 607 | /** 608 | * @dev Returns the decimals places of the token. 609 | */ 610 | function decimals() external view returns (uint8); 611 | } 612 | 613 | // File: @openzeppelin/contracts@4.9.5/token/ERC20/ERC20.sol 614 | 615 | 616 | // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) 617 | 618 | pragma solidity ^0.8.0; 619 | 620 | 621 | 622 | 623 | /** 624 | * @dev Implementation of the {IERC20} interface. 625 | * 626 | * This implementation is agnostic to the way tokens are created. This means 627 | * that a supply mechanism has to be added in a derived contract using {_mint}. 628 | * For a generic mechanism see {ERC20PresetMinterPauser}. 629 | * 630 | * TIP: For a detailed writeup see our guide 631 | * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How 632 | * to implement supply mechanisms]. 633 | * 634 | * The default value of {decimals} is 18. To change this, you should override 635 | * this function so it returns a different value. 636 | * 637 | * We have followed general OpenZeppelin Contracts guidelines: functions revert 638 | * instead returning `false` on failure. This behavior is nonetheless 639 | * conventional and does not conflict with the expectations of ERC20 640 | * applications. 641 | * 642 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 643 | * This allows applications to reconstruct the allowance for all accounts just 644 | * by listening to said events. Other implementations of the EIP may not emit 645 | * these events, as it isn't required by the specification. 646 | * 647 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 648 | * functions have been added to mitigate the well-known issues around setting 649 | * allowances. See {IERC20-approve}. 650 | */ 651 | contract ERC20 is Context, IERC20, IERC20Metadata { 652 | mapping(address => uint256) private _balances; 653 | 654 | mapping(address => mapping(address => uint256)) private _allowances; 655 | 656 | uint256 private _totalSupply; 657 | 658 | string private _name; 659 | string private _symbol; 660 | 661 | /** 662 | * @dev Sets the values for {name} and {symbol}. 663 | * 664 | * All two of these values are immutable: they can only be set once during 665 | * construction. 666 | */ 667 | constructor(string memory name_, string memory symbol_) { 668 | _name = name_; 669 | _symbol = symbol_; 670 | } 671 | 672 | /** 673 | * @dev Returns the name of the token. 674 | */ 675 | function name() public view virtual override returns (string memory) { 676 | return _name; 677 | } 678 | 679 | /** 680 | * @dev Returns the symbol of the token, usually a shorter version of the 681 | * name. 682 | */ 683 | function symbol() public view virtual override returns (string memory) { 684 | return _symbol; 685 | } 686 | 687 | /** 688 | * @dev Returns the number of decimals used to get its user representation. 689 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 690 | * be displayed to a user as `5.05` (`505 / 10 ** 2`). 691 | * 692 | * Tokens usually opt for a value of 18, imitating the relationship between 693 | * Ether and Wei. This is the default value returned by this function, unless 694 | * it's overridden. 695 | * 696 | * NOTE: This information is only used for _display_ purposes: it in 697 | * no way affects any of the arithmetic of the contract, including 698 | * {IERC20-balanceOf} and {IERC20-transfer}. 699 | */ 700 | function decimals() public view virtual override returns (uint8) { 701 | return 18; 702 | } 703 | 704 | /** 705 | * @dev See {IERC20-totalSupply}. 706 | */ 707 | function totalSupply() public view virtual override returns (uint256) { 708 | return _totalSupply; 709 | } 710 | 711 | /** 712 | * @dev See {IERC20-balanceOf}. 713 | */ 714 | function balanceOf(address account) public view virtual override returns (uint256) { 715 | return _balances[account]; 716 | } 717 | 718 | /** 719 | * @dev See {IERC20-transfer}. 720 | * 721 | * Requirements: 722 | * 723 | * - `to` cannot be the zero address. 724 | * - the caller must have a balance of at least `amount`. 725 | */ 726 | function transfer(address to, uint256 amount) public virtual override returns (bool) { 727 | address owner = _msgSender(); 728 | _transfer(owner, to, amount); 729 | return true; 730 | } 731 | 732 | /** 733 | * @dev See {IERC20-allowance}. 734 | */ 735 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 736 | return _allowances[owner][spender]; 737 | } 738 | 739 | /** 740 | * @dev See {IERC20-approve}. 741 | * 742 | * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on 743 | * `transferFrom`. This is semantically equivalent to an infinite approval. 744 | * 745 | * Requirements: 746 | * 747 | * - `spender` cannot be the zero address. 748 | */ 749 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 750 | address owner = _msgSender(); 751 | _approve(owner, spender, amount); 752 | return true; 753 | } 754 | 755 | /** 756 | * @dev See {IERC20-transferFrom}. 757 | * 758 | * Emits an {Approval} event indicating the updated allowance. This is not 759 | * required by the EIP. See the note at the beginning of {ERC20}. 760 | * 761 | * NOTE: Does not update the allowance if the current allowance 762 | * is the maximum `uint256`. 763 | * 764 | * Requirements: 765 | * 766 | * - `from` and `to` cannot be the zero address. 767 | * - `from` must have a balance of at least `amount`. 768 | * - the caller must have allowance for ``from``'s tokens of at least 769 | * `amount`. 770 | */ 771 | function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { 772 | address spender = _msgSender(); 773 | _spendAllowance(from, spender, amount); 774 | _transfer(from, to, amount); 775 | return true; 776 | } 777 | 778 | /** 779 | * @dev Atomically increases the allowance granted to `spender` by the caller. 780 | * 781 | * This is an alternative to {approve} that can be used as a mitigation for 782 | * problems described in {IERC20-approve}. 783 | * 784 | * Emits an {Approval} event indicating the updated allowance. 785 | * 786 | * Requirements: 787 | * 788 | * - `spender` cannot be the zero address. 789 | */ 790 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 791 | address owner = _msgSender(); 792 | _approve(owner, spender, allowance(owner, spender) + addedValue); 793 | return true; 794 | } 795 | 796 | /** 797 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 798 | * 799 | * This is an alternative to {approve} that can be used as a mitigation for 800 | * problems described in {IERC20-approve}. 801 | * 802 | * Emits an {Approval} event indicating the updated allowance. 803 | * 804 | * Requirements: 805 | * 806 | * - `spender` cannot be the zero address. 807 | * - `spender` must have allowance for the caller of at least 808 | * `subtractedValue`. 809 | */ 810 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 811 | address owner = _msgSender(); 812 | uint256 currentAllowance = allowance(owner, spender); 813 | require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); 814 | unchecked { 815 | _approve(owner, spender, currentAllowance - subtractedValue); 816 | } 817 | 818 | return true; 819 | } 820 | 821 | /** 822 | * @dev Moves `amount` of tokens from `from` to `to`. 823 | * 824 | * This internal function is equivalent to {transfer}, and can be used to 825 | * e.g. implement automatic token fees, slashing mechanisms, etc. 826 | * 827 | * Emits a {Transfer} event. 828 | * 829 | * Requirements: 830 | * 831 | * - `from` cannot be the zero address. 832 | * - `to` cannot be the zero address. 833 | * - `from` must have a balance of at least `amount`. 834 | */ 835 | function _transfer(address from, address to, uint256 amount) internal virtual { 836 | require(from != address(0), "ERC20: transfer from the zero address"); 837 | require(to != address(0), "ERC20: transfer to the zero address"); 838 | 839 | _beforeTokenTransfer(from, to, amount); 840 | 841 | uint256 fromBalance = _balances[from]; 842 | require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); 843 | unchecked { 844 | _balances[from] = fromBalance - amount; 845 | // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by 846 | // decrementing then incrementing. 847 | _balances[to] += amount; 848 | } 849 | 850 | emit Transfer(from, to, amount); 851 | 852 | _afterTokenTransfer(from, to, amount); 853 | } 854 | 855 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 856 | * the total supply. 857 | * 858 | * Emits a {Transfer} event with `from` set to the zero address. 859 | * 860 | * Requirements: 861 | * 862 | * - `account` cannot be the zero address. 863 | */ 864 | function _mint(address account, uint256 amount) internal virtual { 865 | require(account != address(0), "ERC20: mint to the zero address"); 866 | 867 | _beforeTokenTransfer(address(0), account, amount); 868 | 869 | _totalSupply += amount; 870 | unchecked { 871 | // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. 872 | _balances[account] += amount; 873 | } 874 | emit Transfer(address(0), account, amount); 875 | 876 | _afterTokenTransfer(address(0), account, amount); 877 | } 878 | 879 | /** 880 | * @dev Destroys `amount` tokens from `account`, reducing the 881 | * total supply. 882 | * 883 | * Emits a {Transfer} event with `to` set to the zero address. 884 | * 885 | * Requirements: 886 | * 887 | * - `account` cannot be the zero address. 888 | * - `account` must have at least `amount` tokens. 889 | */ 890 | function _burn(address account, uint256 amount) internal virtual { 891 | require(account != address(0), "ERC20: burn from the zero address"); 892 | 893 | _beforeTokenTransfer(account, address(0), amount); 894 | 895 | uint256 accountBalance = _balances[account]; 896 | require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); 897 | unchecked { 898 | _balances[account] = accountBalance - amount; 899 | // Overflow not possible: amount <= accountBalance <= totalSupply. 900 | _totalSupply -= amount; 901 | } 902 | 903 | emit Transfer(account, address(0), amount); 904 | 905 | _afterTokenTransfer(account, address(0), amount); 906 | } 907 | 908 | /** 909 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 910 | * 911 | * This internal function is equivalent to `approve`, and can be used to 912 | * e.g. set automatic allowances for certain subsystems, etc. 913 | * 914 | * Emits an {Approval} event. 915 | * 916 | * Requirements: 917 | * 918 | * - `owner` cannot be the zero address. 919 | * - `spender` cannot be the zero address. 920 | */ 921 | function _approve(address owner, address spender, uint256 amount) internal virtual { 922 | require(owner != address(0), "ERC20: approve from the zero address"); 923 | require(spender != address(0), "ERC20: approve to the zero address"); 924 | 925 | _allowances[owner][spender] = amount; 926 | emit Approval(owner, spender, amount); 927 | } 928 | 929 | /** 930 | * @dev Updates `owner` s allowance for `spender` based on spent `amount`. 931 | * 932 | * Does not update the allowance amount in case of infinite allowance. 933 | * Revert if not enough allowance is available. 934 | * 935 | * Might emit an {Approval} event. 936 | */ 937 | function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { 938 | uint256 currentAllowance = allowance(owner, spender); 939 | if (currentAllowance != type(uint256).max) { 940 | require(currentAllowance >= amount, "ERC20: insufficient allowance"); 941 | unchecked { 942 | _approve(owner, spender, currentAllowance - amount); 943 | } 944 | } 945 | } 946 | 947 | /** 948 | * @dev Hook that is called before any transfer of tokens. This includes 949 | * minting and burning. 950 | * 951 | * Calling conditions: 952 | * 953 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 954 | * will be transferred to `to`. 955 | * - when `from` is zero, `amount` tokens will be minted for `to`. 956 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 957 | * - `from` and `to` are never both zero. 958 | * 959 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 960 | */ 961 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 962 | 963 | /** 964 | * @dev Hook that is called after any transfer of tokens. This includes 965 | * minting and burning. 966 | * 967 | * Calling conditions: 968 | * 969 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 970 | * has been transferred to `to`. 971 | * - when `from` is zero, `amount` tokens have been minted for `to`. 972 | * - when `to` is zero, `amount` of ``from``'s tokens have been burned. 973 | * - `from` and `to` are never both zero. 974 | * 975 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 976 | */ 977 | function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} 978 | } 979 | 980 | // File: @openzeppelin/contracts@4.9.5/utils/StorageSlot.sol 981 | 982 | 983 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) 984 | // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. 985 | 986 | pragma solidity ^0.8.0; 987 | 988 | /** 989 | * @dev Library for reading and writing primitive types to specific storage slots. 990 | * 991 | * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. 992 | * This library helps with reading and writing to such slots without the need for inline assembly. 993 | * 994 | * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. 995 | * 996 | * Example usage to set ERC1967 implementation slot: 997 | * ```solidity 998 | * contract ERC1967 { 999 | * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; 1000 | * 1001 | * function _getImplementation() internal view returns (address) { 1002 | * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; 1003 | * } 1004 | * 1005 | * function _setImplementation(address newImplementation) internal { 1006 | * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); 1007 | * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; 1008 | * } 1009 | * } 1010 | * ``` 1011 | * 1012 | * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ 1013 | * _Available since v4.9 for `string`, `bytes`._ 1014 | */ 1015 | library StorageSlot { 1016 | struct AddressSlot { 1017 | address value; 1018 | } 1019 | 1020 | struct BooleanSlot { 1021 | bool value; 1022 | } 1023 | 1024 | struct Bytes32Slot { 1025 | bytes32 value; 1026 | } 1027 | 1028 | struct Uint256Slot { 1029 | uint256 value; 1030 | } 1031 | 1032 | struct StringSlot { 1033 | string value; 1034 | } 1035 | 1036 | struct BytesSlot { 1037 | bytes value; 1038 | } 1039 | 1040 | /** 1041 | * @dev Returns an `AddressSlot` with member `value` located at `slot`. 1042 | */ 1043 | function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { 1044 | /// @solidity memory-safe-assembly 1045 | assembly { 1046 | r.slot := slot 1047 | } 1048 | } 1049 | 1050 | /** 1051 | * @dev Returns an `BooleanSlot` with member `value` located at `slot`. 1052 | */ 1053 | function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { 1054 | /// @solidity memory-safe-assembly 1055 | assembly { 1056 | r.slot := slot 1057 | } 1058 | } 1059 | 1060 | /** 1061 | * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. 1062 | */ 1063 | function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { 1064 | /// @solidity memory-safe-assembly 1065 | assembly { 1066 | r.slot := slot 1067 | } 1068 | } 1069 | 1070 | /** 1071 | * @dev Returns an `Uint256Slot` with member `value` located at `slot`. 1072 | */ 1073 | function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { 1074 | /// @solidity memory-safe-assembly 1075 | assembly { 1076 | r.slot := slot 1077 | } 1078 | } 1079 | 1080 | /** 1081 | * @dev Returns an `StringSlot` with member `value` located at `slot`. 1082 | */ 1083 | function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { 1084 | /// @solidity memory-safe-assembly 1085 | assembly { 1086 | r.slot := slot 1087 | } 1088 | } 1089 | 1090 | /** 1091 | * @dev Returns an `StringSlot` representation of the string storage pointer `store`. 1092 | */ 1093 | function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { 1094 | /// @solidity memory-safe-assembly 1095 | assembly { 1096 | r.slot := store.slot 1097 | } 1098 | } 1099 | 1100 | /** 1101 | * @dev Returns an `BytesSlot` with member `value` located at `slot`. 1102 | */ 1103 | function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { 1104 | /// @solidity memory-safe-assembly 1105 | assembly { 1106 | r.slot := slot 1107 | } 1108 | } 1109 | 1110 | /** 1111 | * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. 1112 | */ 1113 | function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { 1114 | /// @solidity memory-safe-assembly 1115 | assembly { 1116 | r.slot := store.slot 1117 | } 1118 | } 1119 | } 1120 | 1121 | // File: @openzeppelin/contracts@4.9.5/utils/math/Math.sol 1122 | 1123 | 1124 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) 1125 | 1126 | pragma solidity ^0.8.0; 1127 | 1128 | /** 1129 | * @dev Standard math utilities missing in the Solidity language. 1130 | */ 1131 | library Math { 1132 | enum Rounding { 1133 | Down, // Toward negative infinity 1134 | Up, // Toward infinity 1135 | Zero // Toward zero 1136 | } 1137 | 1138 | /** 1139 | * @dev Returns the largest of two numbers. 1140 | */ 1141 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 1142 | return a > b ? a : b; 1143 | } 1144 | 1145 | /** 1146 | * @dev Returns the smallest of two numbers. 1147 | */ 1148 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 1149 | return a < b ? a : b; 1150 | } 1151 | 1152 | /** 1153 | * @dev Returns the average of two numbers. The result is rounded towards 1154 | * zero. 1155 | */ 1156 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 1157 | // (a + b) / 2 can overflow. 1158 | return (a & b) + (a ^ b) / 2; 1159 | } 1160 | 1161 | /** 1162 | * @dev Returns the ceiling of the division of two numbers. 1163 | * 1164 | * This differs from standard division with `/` in that it rounds up instead 1165 | * of rounding down. 1166 | */ 1167 | function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { 1168 | // (a + b - 1) / b can overflow on addition, so we distribute. 1169 | return a == 0 ? 0 : (a - 1) / b + 1; 1170 | } 1171 | 1172 | /** 1173 | * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 1174 | * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) 1175 | * with further edits by Uniswap Labs also under MIT license. 1176 | */ 1177 | function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { 1178 | unchecked { 1179 | // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use 1180 | // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 1181 | // variables such that product = prod1 * 2^256 + prod0. 1182 | uint256 prod0; // Least significant 256 bits of the product 1183 | uint256 prod1; // Most significant 256 bits of the product 1184 | assembly { 1185 | let mm := mulmod(x, y, not(0)) 1186 | prod0 := mul(x, y) 1187 | prod1 := sub(sub(mm, prod0), lt(mm, prod0)) 1188 | } 1189 | 1190 | // Handle non-overflow cases, 256 by 256 division. 1191 | if (prod1 == 0) { 1192 | // Solidity will revert if denominator == 0, unlike the div opcode on its own. 1193 | // The surrounding unchecked block does not change this fact. 1194 | // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. 1195 | return prod0 / denominator; 1196 | } 1197 | 1198 | // Make sure the result is less than 2^256. Also prevents denominator == 0. 1199 | require(denominator > prod1, "Math: mulDiv overflow"); 1200 | 1201 | /////////////////////////////////////////////// 1202 | // 512 by 256 division. 1203 | /////////////////////////////////////////////// 1204 | 1205 | // Make division exact by subtracting the remainder from [prod1 prod0]. 1206 | uint256 remainder; 1207 | assembly { 1208 | // Compute remainder using mulmod. 1209 | remainder := mulmod(x, y, denominator) 1210 | 1211 | // Subtract 256 bit number from 512 bit number. 1212 | prod1 := sub(prod1, gt(remainder, prod0)) 1213 | prod0 := sub(prod0, remainder) 1214 | } 1215 | 1216 | // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. 1217 | // See https://cs.stackexchange.com/q/138556/92363. 1218 | 1219 | // Does not overflow because the denominator cannot be zero at this stage in the function. 1220 | uint256 twos = denominator & (~denominator + 1); 1221 | assembly { 1222 | // Divide denominator by twos. 1223 | denominator := div(denominator, twos) 1224 | 1225 | // Divide [prod1 prod0] by twos. 1226 | prod0 := div(prod0, twos) 1227 | 1228 | // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. 1229 | twos := add(div(sub(0, twos), twos), 1) 1230 | } 1231 | 1232 | // Shift in bits from prod1 into prod0. 1233 | prod0 |= prod1 * twos; 1234 | 1235 | // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such 1236 | // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for 1237 | // four bits. That is, denominator * inv = 1 mod 2^4. 1238 | uint256 inverse = (3 * denominator) ^ 2; 1239 | 1240 | // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works 1241 | // in modular arithmetic, doubling the correct bits in each step. 1242 | inverse *= 2 - denominator * inverse; // inverse mod 2^8 1243 | inverse *= 2 - denominator * inverse; // inverse mod 2^16 1244 | inverse *= 2 - denominator * inverse; // inverse mod 2^32 1245 | inverse *= 2 - denominator * inverse; // inverse mod 2^64 1246 | inverse *= 2 - denominator * inverse; // inverse mod 2^128 1247 | inverse *= 2 - denominator * inverse; // inverse mod 2^256 1248 | 1249 | // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. 1250 | // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is 1251 | // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 1252 | // is no longer required. 1253 | result = prod0 * inverse; 1254 | return result; 1255 | } 1256 | } 1257 | 1258 | /** 1259 | * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. 1260 | */ 1261 | function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { 1262 | uint256 result = mulDiv(x, y, denominator); 1263 | if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { 1264 | result += 1; 1265 | } 1266 | return result; 1267 | } 1268 | 1269 | /** 1270 | * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. 1271 | * 1272 | * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). 1273 | */ 1274 | function sqrt(uint256 a) internal pure returns (uint256) { 1275 | if (a == 0) { 1276 | return 0; 1277 | } 1278 | 1279 | // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. 1280 | // 1281 | // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have 1282 | // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. 1283 | // 1284 | // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` 1285 | // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` 1286 | // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` 1287 | // 1288 | // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. 1289 | uint256 result = 1 << (log2(a) >> 1); 1290 | 1291 | // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, 1292 | // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at 1293 | // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision 1294 | // into the expected uint128 result. 1295 | unchecked { 1296 | result = (result + a / result) >> 1; 1297 | result = (result + a / result) >> 1; 1298 | result = (result + a / result) >> 1; 1299 | result = (result + a / result) >> 1; 1300 | result = (result + a / result) >> 1; 1301 | result = (result + a / result) >> 1; 1302 | result = (result + a / result) >> 1; 1303 | return min(result, a / result); 1304 | } 1305 | } 1306 | 1307 | /** 1308 | * @notice Calculates sqrt(a), following the selected rounding direction. 1309 | */ 1310 | function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { 1311 | unchecked { 1312 | uint256 result = sqrt(a); 1313 | return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); 1314 | } 1315 | } 1316 | 1317 | /** 1318 | * @dev Return the log in base 2, rounded down, of a positive value. 1319 | * Returns 0 if given 0. 1320 | */ 1321 | function log2(uint256 value) internal pure returns (uint256) { 1322 | uint256 result = 0; 1323 | unchecked { 1324 | if (value >> 128 > 0) { 1325 | value >>= 128; 1326 | result += 128; 1327 | } 1328 | if (value >> 64 > 0) { 1329 | value >>= 64; 1330 | result += 64; 1331 | } 1332 | if (value >> 32 > 0) { 1333 | value >>= 32; 1334 | result += 32; 1335 | } 1336 | if (value >> 16 > 0) { 1337 | value >>= 16; 1338 | result += 16; 1339 | } 1340 | if (value >> 8 > 0) { 1341 | value >>= 8; 1342 | result += 8; 1343 | } 1344 | if (value >> 4 > 0) { 1345 | value >>= 4; 1346 | result += 4; 1347 | } 1348 | if (value >> 2 > 0) { 1349 | value >>= 2; 1350 | result += 2; 1351 | } 1352 | if (value >> 1 > 0) { 1353 | result += 1; 1354 | } 1355 | } 1356 | return result; 1357 | } 1358 | 1359 | /** 1360 | * @dev Return the log in base 2, following the selected rounding direction, of a positive value. 1361 | * Returns 0 if given 0. 1362 | */ 1363 | function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { 1364 | unchecked { 1365 | uint256 result = log2(value); 1366 | return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); 1367 | } 1368 | } 1369 | 1370 | /** 1371 | * @dev Return the log in base 10, rounded down, of a positive value. 1372 | * Returns 0 if given 0. 1373 | */ 1374 | function log10(uint256 value) internal pure returns (uint256) { 1375 | uint256 result = 0; 1376 | unchecked { 1377 | if (value >= 10 ** 64) { 1378 | value /= 10 ** 64; 1379 | result += 64; 1380 | } 1381 | if (value >= 10 ** 32) { 1382 | value /= 10 ** 32; 1383 | result += 32; 1384 | } 1385 | if (value >= 10 ** 16) { 1386 | value /= 10 ** 16; 1387 | result += 16; 1388 | } 1389 | if (value >= 10 ** 8) { 1390 | value /= 10 ** 8; 1391 | result += 8; 1392 | } 1393 | if (value >= 10 ** 4) { 1394 | value /= 10 ** 4; 1395 | result += 4; 1396 | } 1397 | if (value >= 10 ** 2) { 1398 | value /= 10 ** 2; 1399 | result += 2; 1400 | } 1401 | if (value >= 10 ** 1) { 1402 | result += 1; 1403 | } 1404 | } 1405 | return result; 1406 | } 1407 | 1408 | /** 1409 | * @dev Return the log in base 10, following the selected rounding direction, of a positive value. 1410 | * Returns 0 if given 0. 1411 | */ 1412 | function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { 1413 | unchecked { 1414 | uint256 result = log10(value); 1415 | return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); 1416 | } 1417 | } 1418 | 1419 | /** 1420 | * @dev Return the log in base 256, rounded down, of a positive value. 1421 | * Returns 0 if given 0. 1422 | * 1423 | * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. 1424 | */ 1425 | function log256(uint256 value) internal pure returns (uint256) { 1426 | uint256 result = 0; 1427 | unchecked { 1428 | if (value >> 128 > 0) { 1429 | value >>= 128; 1430 | result += 16; 1431 | } 1432 | if (value >> 64 > 0) { 1433 | value >>= 64; 1434 | result += 8; 1435 | } 1436 | if (value >> 32 > 0) { 1437 | value >>= 32; 1438 | result += 4; 1439 | } 1440 | if (value >> 16 > 0) { 1441 | value >>= 16; 1442 | result += 2; 1443 | } 1444 | if (value >> 8 > 0) { 1445 | result += 1; 1446 | } 1447 | } 1448 | return result; 1449 | } 1450 | 1451 | /** 1452 | * @dev Return the log in base 256, following the selected rounding direction, of a positive value. 1453 | * Returns 0 if given 0. 1454 | */ 1455 | function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { 1456 | unchecked { 1457 | uint256 result = log256(value); 1458 | return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); 1459 | } 1460 | } 1461 | } 1462 | 1463 | // File: @openzeppelin/contracts@4.9.5/utils/Arrays.sol 1464 | 1465 | 1466 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/Arrays.sol) 1467 | 1468 | pragma solidity ^0.8.0; 1469 | 1470 | 1471 | 1472 | /** 1473 | * @dev Collection of functions related to array types. 1474 | */ 1475 | library Arrays { 1476 | using StorageSlot for bytes32; 1477 | 1478 | /** 1479 | * @dev Searches a sorted `array` and returns the first index that contains 1480 | * a value greater or equal to `element`. If no such index exists (i.e. all 1481 | * values in the array are strictly less than `element`), the array length is 1482 | * returned. Time complexity O(log n). 1483 | * 1484 | * `array` is expected to be sorted in ascending order, and to contain no 1485 | * repeated elements. 1486 | */ 1487 | function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { 1488 | if (array.length == 0) { 1489 | return 0; 1490 | } 1491 | 1492 | uint256 low = 0; 1493 | uint256 high = array.length; 1494 | 1495 | while (low < high) { 1496 | uint256 mid = Math.average(low, high); 1497 | 1498 | // Note that mid will always be strictly less than high (i.e. it will be a valid array index) 1499 | // because Math.average rounds down (it does integer division with truncation). 1500 | if (unsafeAccess(array, mid).value > element) { 1501 | high = mid; 1502 | } else { 1503 | low = mid + 1; 1504 | } 1505 | } 1506 | 1507 | // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. 1508 | if (low > 0 && unsafeAccess(array, low - 1).value == element) { 1509 | return low - 1; 1510 | } else { 1511 | return low; 1512 | } 1513 | } 1514 | 1515 | /** 1516 | * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. 1517 | * 1518 | * WARNING: Only use if you are certain `pos` is lower than the array length. 1519 | */ 1520 | function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) { 1521 | bytes32 slot; 1522 | // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr` 1523 | // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays. 1524 | 1525 | /// @solidity memory-safe-assembly 1526 | assembly { 1527 | mstore(0, arr.slot) 1528 | slot := add(keccak256(0, 0x20), pos) 1529 | } 1530 | return slot.getAddressSlot(); 1531 | } 1532 | 1533 | /** 1534 | * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. 1535 | * 1536 | * WARNING: Only use if you are certain `pos` is lower than the array length. 1537 | */ 1538 | function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) { 1539 | bytes32 slot; 1540 | // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr` 1541 | // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays. 1542 | 1543 | /// @solidity memory-safe-assembly 1544 | assembly { 1545 | mstore(0, arr.slot) 1546 | slot := add(keccak256(0, 0x20), pos) 1547 | } 1548 | return slot.getBytes32Slot(); 1549 | } 1550 | 1551 | /** 1552 | * @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check. 1553 | * 1554 | * WARNING: Only use if you are certain `pos` is lower than the array length. 1555 | */ 1556 | function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) { 1557 | bytes32 slot; 1558 | // We use assembly to calculate the storage slot of the element at index `pos` of the dynamic array `arr` 1559 | // following https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#mappings-and-dynamic-arrays. 1560 | 1561 | /// @solidity memory-safe-assembly 1562 | assembly { 1563 | mstore(0, arr.slot) 1564 | slot := add(keccak256(0, 0x20), pos) 1565 | } 1566 | return slot.getUint256Slot(); 1567 | } 1568 | } 1569 | 1570 | // File: @openzeppelin/contracts@4.9.5/utils/Counters.sol 1571 | 1572 | 1573 | // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) 1574 | 1575 | pragma solidity ^0.8.0; 1576 | 1577 | /** 1578 | * @title Counters 1579 | * @author Matt Condon (@shrugs) 1580 | * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number 1581 | * of elements in a mapping, issuing ERC721 ids, or counting request ids. 1582 | * 1583 | * Include with `using Counters for Counters.Counter;` 1584 | */ 1585 | library Counters { 1586 | struct Counter { 1587 | // This variable should never be directly accessed by users of the library: interactions must be restricted to 1588 | // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add 1589 | // this feature: see https://github.com/ethereum/solidity/issues/4637 1590 | uint256 _value; // default: 0 1591 | } 1592 | 1593 | function current(Counter storage counter) internal view returns (uint256) { 1594 | return counter._value; 1595 | } 1596 | 1597 | function increment(Counter storage counter) internal { 1598 | unchecked { 1599 | counter._value += 1; 1600 | } 1601 | } 1602 | 1603 | function decrement(Counter storage counter) internal { 1604 | uint256 value = counter._value; 1605 | require(value > 0, "Counter: decrement overflow"); 1606 | unchecked { 1607 | counter._value = value - 1; 1608 | } 1609 | } 1610 | 1611 | function reset(Counter storage counter) internal { 1612 | counter._value = 0; 1613 | } 1614 | } 1615 | 1616 | // File: @openzeppelin/contracts@4.9.5/token/ERC20/extensions/ERC20Snapshot.sol 1617 | 1618 | 1619 | // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Snapshot.sol) 1620 | 1621 | pragma solidity ^0.8.0; 1622 | 1623 | 1624 | 1625 | 1626 | /** 1627 | * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and 1628 | * total supply at the time are recorded for later access. 1629 | * 1630 | * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. 1631 | * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different 1632 | * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be 1633 | * used to create an efficient ERC20 forking mechanism. 1634 | * 1635 | * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a 1636 | * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot 1637 | * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id 1638 | * and the account address. 1639 | * 1640 | * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it 1641 | * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this 1642 | * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. 1643 | * 1644 | * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient 1645 | * alternative consider {ERC20Votes}. 1646 | * 1647 | * ==== Gas Costs 1648 | * 1649 | * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log 1650 | * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much 1651 | * smaller since identical balances in subsequent snapshots are stored as a single entry. 1652 | * 1653 | * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is 1654 | * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent 1655 | * transfers will have normal cost until the next snapshot, and so on. 1656 | */ 1657 | 1658 | abstract contract ERC20Snapshot is ERC20 { 1659 | // Inspired by Jordi Baylina's MiniMeToken to record historical balances: 1660 | // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol 1661 | 1662 | using Arrays for uint256[]; 1663 | using Counters for Counters.Counter; 1664 | 1665 | // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a 1666 | // Snapshot struct, but that would impede usage of functions that work on an array. 1667 | struct Snapshots { 1668 | uint256[] ids; 1669 | uint256[] values; 1670 | } 1671 | 1672 | mapping(address => Snapshots) private _accountBalanceSnapshots; 1673 | Snapshots private _totalSupplySnapshots; 1674 | 1675 | // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. 1676 | Counters.Counter private _currentSnapshotId; 1677 | 1678 | /** 1679 | * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. 1680 | */ 1681 | event Snapshot(uint256 id); 1682 | 1683 | /** 1684 | * @dev Creates a new snapshot and returns its snapshot id. 1685 | * 1686 | * Emits a {Snapshot} event that contains the same id. 1687 | * 1688 | * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a 1689 | * set of accounts, for example using {AccessControl}, or it may be open to the public. 1690 | * 1691 | * [WARNING] 1692 | * ==== 1693 | * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, 1694 | * you must consider that it can potentially be used by attackers in two ways. 1695 | * 1696 | * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow 1697 | * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target 1698 | * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs 1699 | * section above. 1700 | * 1701 | * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. 1702 | * ==== 1703 | */ 1704 | function _snapshot() internal virtual returns (uint256) { 1705 | _currentSnapshotId.increment(); 1706 | 1707 | uint256 currentId = _getCurrentSnapshotId(); 1708 | emit Snapshot(currentId); 1709 | return currentId; 1710 | } 1711 | 1712 | /** 1713 | * @dev Get the current snapshotId 1714 | */ 1715 | function _getCurrentSnapshotId() internal view virtual returns (uint256) { 1716 | return _currentSnapshotId.current(); 1717 | } 1718 | 1719 | /** 1720 | * @dev Retrieves the balance of `account` at the time `snapshotId` was created. 1721 | */ 1722 | function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { 1723 | (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); 1724 | 1725 | return snapshotted ? value : balanceOf(account); 1726 | } 1727 | 1728 | /** 1729 | * @dev Retrieves the total supply at the time `snapshotId` was created. 1730 | */ 1731 | function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { 1732 | (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); 1733 | 1734 | return snapshotted ? value : totalSupply(); 1735 | } 1736 | 1737 | // Update balance and/or total supply snapshots before the values are modified. This is implemented 1738 | // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. 1739 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { 1740 | super._beforeTokenTransfer(from, to, amount); 1741 | 1742 | if (from == address(0)) { 1743 | // mint 1744 | _updateAccountSnapshot(to); 1745 | _updateTotalSupplySnapshot(); 1746 | } else if (to == address(0)) { 1747 | // burn 1748 | _updateAccountSnapshot(from); 1749 | _updateTotalSupplySnapshot(); 1750 | } else { 1751 | // transfer 1752 | _updateAccountSnapshot(from); 1753 | _updateAccountSnapshot(to); 1754 | } 1755 | } 1756 | 1757 | function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { 1758 | require(snapshotId > 0, "ERC20Snapshot: id is 0"); 1759 | require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); 1760 | 1761 | // When a valid snapshot is queried, there are three possibilities: 1762 | // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never 1763 | // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds 1764 | // to this id is the current one. 1765 | // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the 1766 | // requested id, and its value is the one to return. 1767 | // c) More snapshots were created after the requested one, and the queried value was later modified. There will be 1768 | // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is 1769 | // larger than the requested one. 1770 | // 1771 | // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if 1772 | // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does 1773 | // exactly this. 1774 | 1775 | uint256 index = snapshots.ids.findUpperBound(snapshotId); 1776 | 1777 | if (index == snapshots.ids.length) { 1778 | return (false, 0); 1779 | } else { 1780 | return (true, snapshots.values[index]); 1781 | } 1782 | } 1783 | 1784 | function _updateAccountSnapshot(address account) private { 1785 | _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); 1786 | } 1787 | 1788 | function _updateTotalSupplySnapshot() private { 1789 | _updateSnapshot(_totalSupplySnapshots, totalSupply()); 1790 | } 1791 | 1792 | function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { 1793 | uint256 currentId = _getCurrentSnapshotId(); 1794 | if (_lastSnapshotId(snapshots.ids) < currentId) { 1795 | snapshots.ids.push(currentId); 1796 | snapshots.values.push(currentValue); 1797 | } 1798 | } 1799 | 1800 | function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { 1801 | if (ids.length == 0) { 1802 | return 0; 1803 | } else { 1804 | return ids[ids.length - 1]; 1805 | } 1806 | } 1807 | } 1808 | 1809 | // File: @openzeppelin/contracts@4.9.5/utils/math/SafeMath.sol 1810 | 1811 | 1812 | // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) 1813 | 1814 | pragma solidity ^0.8.0; 1815 | 1816 | // CAUTION 1817 | // This version of SafeMath should only be used with Solidity 0.8 or later, 1818 | // because it relies on the compiler's built in overflow checks. 1819 | 1820 | /** 1821 | * @dev Wrappers over Solidity's arithmetic operations. 1822 | * 1823 | * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler 1824 | * now has built in overflow checking. 1825 | */ 1826 | library SafeMath { 1827 | /** 1828 | * @dev Returns the addition of two unsigned integers, with an overflow flag. 1829 | * 1830 | * _Available since v3.4._ 1831 | */ 1832 | function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 1833 | unchecked { 1834 | uint256 c = a + b; 1835 | if (c < a) return (false, 0); 1836 | return (true, c); 1837 | } 1838 | } 1839 | 1840 | /** 1841 | * @dev Returns the subtraction of two unsigned integers, with an overflow flag. 1842 | * 1843 | * _Available since v3.4._ 1844 | */ 1845 | function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { 1846 | unchecked { 1847 | if (b > a) return (false, 0); 1848 | return (true, a - b); 1849 | } 1850 | } 1851 | 1852 | /** 1853 | * @dev Returns the multiplication of two unsigned integers, with an overflow flag. 1854 | * 1855 | * _Available since v3.4._ 1856 | */ 1857 | function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { 1858 | unchecked { 1859 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 1860 | // benefit is lost if 'b' is also tested. 1861 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 1862 | if (a == 0) return (true, 0); 1863 | uint256 c = a * b; 1864 | if (c / a != b) return (false, 0); 1865 | return (true, c); 1866 | } 1867 | } 1868 | 1869 | /** 1870 | * @dev Returns the division of two unsigned integers, with a division by zero flag. 1871 | * 1872 | * _Available since v3.4._ 1873 | */ 1874 | function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { 1875 | unchecked { 1876 | if (b == 0) return (false, 0); 1877 | return (true, a / b); 1878 | } 1879 | } 1880 | 1881 | /** 1882 | * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. 1883 | * 1884 | * _Available since v3.4._ 1885 | */ 1886 | function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { 1887 | unchecked { 1888 | if (b == 0) return (false, 0); 1889 | return (true, a % b); 1890 | } 1891 | } 1892 | 1893 | /** 1894 | * @dev Returns the addition of two unsigned integers, reverting on 1895 | * overflow. 1896 | * 1897 | * Counterpart to Solidity's `+` operator. 1898 | * 1899 | * Requirements: 1900 | * 1901 | * - Addition cannot overflow. 1902 | */ 1903 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 1904 | return a + b; 1905 | } 1906 | 1907 | /** 1908 | * @dev Returns the subtraction of two unsigned integers, reverting on 1909 | * overflow (when the result is negative). 1910 | * 1911 | * Counterpart to Solidity's `-` operator. 1912 | * 1913 | * Requirements: 1914 | * 1915 | * - Subtraction cannot overflow. 1916 | */ 1917 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 1918 | return a - b; 1919 | } 1920 | 1921 | /** 1922 | * @dev Returns the multiplication of two unsigned integers, reverting on 1923 | * overflow. 1924 | * 1925 | * Counterpart to Solidity's `*` operator. 1926 | * 1927 | * Requirements: 1928 | * 1929 | * - Multiplication cannot overflow. 1930 | */ 1931 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 1932 | return a * b; 1933 | } 1934 | 1935 | /** 1936 | * @dev Returns the integer division of two unsigned integers, reverting on 1937 | * division by zero. The result is rounded towards zero. 1938 | * 1939 | * Counterpart to Solidity's `/` operator. 1940 | * 1941 | * Requirements: 1942 | * 1943 | * - The divisor cannot be zero. 1944 | */ 1945 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 1946 | return a / b; 1947 | } 1948 | 1949 | /** 1950 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 1951 | * reverting when dividing by zero. 1952 | * 1953 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 1954 | * opcode (which leaves remaining gas untouched) while Solidity uses an 1955 | * invalid opcode to revert (consuming all remaining gas). 1956 | * 1957 | * Requirements: 1958 | * 1959 | * - The divisor cannot be zero. 1960 | */ 1961 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 1962 | return a % b; 1963 | } 1964 | 1965 | /** 1966 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 1967 | * overflow (when the result is negative). 1968 | * 1969 | * CAUTION: This function is deprecated because it requires allocating memory for the error 1970 | * message unnecessarily. For custom revert reasons use {trySub}. 1971 | * 1972 | * Counterpart to Solidity's `-` operator. 1973 | * 1974 | * Requirements: 1975 | * 1976 | * - Subtraction cannot overflow. 1977 | */ 1978 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 1979 | unchecked { 1980 | require(b <= a, errorMessage); 1981 | return a - b; 1982 | } 1983 | } 1984 | 1985 | /** 1986 | * @dev Returns the integer division of two unsigned integers, reverting with custom message on 1987 | * division by zero. The result is rounded towards zero. 1988 | * 1989 | * Counterpart to Solidity's `/` operator. Note: this function uses a 1990 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 1991 | * uses an invalid opcode to revert (consuming all remaining gas). 1992 | * 1993 | * Requirements: 1994 | * 1995 | * - The divisor cannot be zero. 1996 | */ 1997 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 1998 | unchecked { 1999 | require(b > 0, errorMessage); 2000 | return a / b; 2001 | } 2002 | } 2003 | 2004 | /** 2005 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 2006 | * reverting with custom message when dividing by zero. 2007 | * 2008 | * CAUTION: This function is deprecated because it requires allocating memory for the error 2009 | * message unnecessarily. For custom revert reasons use {tryMod}. 2010 | * 2011 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 2012 | * opcode (which leaves remaining gas untouched) while Solidity uses an 2013 | * invalid opcode to revert (consuming all remaining gas). 2014 | * 2015 | * Requirements: 2016 | * 2017 | * - The divisor cannot be zero. 2018 | */ 2019 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 2020 | unchecked { 2021 | require(b > 0, errorMessage); 2022 | return a % b; 2023 | } 2024 | } 2025 | } 2026 | 2027 | // File: Launcher/StakeTracker.sol 2028 | 2029 | 2030 | pragma solidity ^0.8.20; 2031 | 2032 | 2033 | 2034 | contract StakeTracker is ERC20Snapshot { 2035 | using SafeMath for uint256; 2036 | 2037 | address private immutable _splitter; 2038 | mapping(uint => uint) public rewardQuantity; 2039 | 2040 | modifier onlySplitter { 2041 | require(msg.sender == _splitter, "Only callable by Splitter"); 2042 | _; 2043 | } 2044 | 2045 | constructor() ERC20("StakeTracker", "ST") { 2046 | _splitter = msg.sender; 2047 | } 2048 | 2049 | function add(address user, uint quantity) external onlySplitter { 2050 | _mint(user, quantity); 2051 | } 2052 | 2053 | function remove(address user, uint quantity) external onlySplitter { 2054 | _burn(user, quantity); 2055 | } 2056 | 2057 | function track(uint quantity) external onlySplitter { 2058 | rewardQuantity[_snapshot()] = quantity; 2059 | } 2060 | 2061 | function calc(address user, uint[] memory snapshotIds) external view onlySplitter returns (uint) { 2062 | uint quantity = 0; 2063 | for (uint i = 0; i < snapshotIds.length; i++) { 2064 | quantity += getUserReward(user, snapshotIds[i]); 2065 | } 2066 | return quantity; 2067 | } 2068 | 2069 | function transfer(address, uint256) public pure override returns (bool) { 2070 | revert("Transfers disabled"); 2071 | } 2072 | 2073 | function transferFrom(address, address, uint256) public pure override returns (bool) { 2074 | revert("Transfers disabled"); 2075 | } 2076 | 2077 | function getUserReward(address user, uint snapshotId) public view returns (uint) { 2078 | uint balanceAt = balanceOfAt(user, snapshotId); 2079 | uint supplyAt = totalSupplyAt(snapshotId); 2080 | if (supplyAt == 0) { 2081 | supplyAt = 1; // Avoid dividing by 0 2082 | } 2083 | uint quantity = rewardQuantity[snapshotId] 2084 | .mul(balanceAt) 2085 | .div(supplyAt); 2086 | 2087 | return quantity; 2088 | } 2089 | 2090 | function getReward(uint snapshotId) external view returns (uint) { 2091 | return rewardQuantity[snapshotId]; 2092 | } 2093 | 2094 | function getCurrentSnapshotId() external view returns (uint) { 2095 | return _getCurrentSnapshotId(); 2096 | } 2097 | 2098 | function getSplitter() external view returns (address) { 2099 | return _splitter; 2100 | } 2101 | } 2102 | 2103 | // File: Launcher/Splitter.sol 2104 | 2105 | 2106 | pragma solidity ^0.8.20; 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | contract Splitter is Rebased, Ownable { 2114 | using EnumerableSet for EnumerableSet.AddressSet; 2115 | 2116 | address private constant _rebase = 0x89fA20b30a88811FBB044821FEC130793185c60B; 2117 | address private immutable _rewardToken; 2118 | address private immutable _stakeToken; 2119 | StakeTracker private immutable _stakeTracker; 2120 | mapping(address => uint) private _startSnapshot; 2121 | mapping(address => uint) private _userEarnings; 2122 | EnumerableSet.AddressSet private _distributors; 2123 | 2124 | modifier onlyRebase { 2125 | require(msg.sender == _rebase, "Only Rebase"); 2126 | _; 2127 | } 2128 | 2129 | modifier onlyDistributor { 2130 | require(_distributors.contains(msg.sender), "Only Distributor"); 2131 | _; 2132 | } 2133 | 2134 | constructor(address stakeToken, address rewardToken) { 2135 | _rewardToken = rewardToken; 2136 | _stakeToken = stakeToken; 2137 | _stakeTracker = new StakeTracker(); 2138 | } 2139 | 2140 | function onStake(address user, address token, uint quantity) external onlyRebase { 2141 | if (token == _stakeToken) { 2142 | _stakeTracker.add(user, quantity); 2143 | if (_startSnapshot[user] == 0) { 2144 | _startSnapshot[user] = _stakeTracker.getCurrentSnapshotId() + 1; 2145 | } 2146 | } 2147 | } 2148 | 2149 | function onUnstake(address user, address token, uint quantity) external onlyRebase { 2150 | if (token == _stakeToken) { 2151 | _stakeTracker.remove(user, quantity); 2152 | } 2153 | } 2154 | 2155 | function split(uint rewardQuantity) external onlyDistributor { 2156 | require( 2157 | IERC20(_rewardToken).transferFrom(msg.sender, address(this), rewardQuantity), 2158 | "Splitter transfer failed" 2159 | ); 2160 | _stakeTracker.track(rewardQuantity); 2161 | } 2162 | 2163 | function claim(address to, uint limit) external { 2164 | uint startSnapshot = _startSnapshot[msg.sender]; 2165 | uint endSnapshot = _stakeTracker.getCurrentSnapshotId(); 2166 | if (startSnapshot > 0 && startSnapshot <= endSnapshot) { 2167 | if (endSnapshot - startSnapshot > limit) { 2168 | endSnapshot = startSnapshot + limit; 2169 | } 2170 | uint[] memory snapshotIds = new uint[](1 + endSnapshot - startSnapshot); 2171 | for (uint i = startSnapshot; i <= endSnapshot; i++) { 2172 | snapshotIds[i - startSnapshot] = i; 2173 | } 2174 | _startSnapshot[msg.sender] = endSnapshot + 1; 2175 | uint quantity = _stakeTracker.calc(msg.sender, snapshotIds); 2176 | if (quantity > 0) { 2177 | _userEarnings[msg.sender] += quantity; 2178 | require(IERC20(_rewardToken).transfer(to, quantity), "Unable to transfer token"); 2179 | } 2180 | } 2181 | } 2182 | 2183 | function getUnclaimedEarnings(address user, uint limit) external view returns (uint quantity) { 2184 | uint startSnapshot = _startSnapshot[user]; 2185 | uint endSnapshot = _stakeTracker.getCurrentSnapshotId(); 2186 | if (startSnapshot > 0 && startSnapshot <= endSnapshot) { 2187 | if (endSnapshot - startSnapshot > limit) { 2188 | endSnapshot = startSnapshot + limit; 2189 | } 2190 | uint[] memory snapshotIds = new uint[](1 + endSnapshot - startSnapshot); 2191 | for (uint i = startSnapshot; i <= endSnapshot; i++) { 2192 | snapshotIds[i - startSnapshot] = i; 2193 | } 2194 | quantity = _stakeTracker.calc(user, snapshotIds); 2195 | } 2196 | } 2197 | 2198 | function getRewardToken() external view returns (address) { 2199 | return _rewardToken; 2200 | } 2201 | function getStakeToken() external view returns (address) { 2202 | return _stakeToken; 2203 | } 2204 | function getStakeTracker() external view returns (address) { 2205 | return address(_stakeTracker); 2206 | } 2207 | function getClaimedEarnings(address user) external view returns (uint) { 2208 | return _userEarnings[user]; 2209 | } 2210 | 2211 | function addDistributor(address distributor) onlyOwner external { 2212 | _distributors.add(distributor); 2213 | } 2214 | function removeDistributor(address distributor) onlyOwner external { 2215 | _distributors.remove(distributor); 2216 | } 2217 | function isDistributor(address distributor) external view returns (bool) { 2218 | return _distributors.contains(distributor); 2219 | } 2220 | function getDistributors() external view returns (address[] memory) { 2221 | return _distributors.values(); 2222 | } 2223 | function getDistributorAt(uint index) external view returns (address) { 2224 | return _distributors.at(index); 2225 | } 2226 | } --------------------------------------------------------------------------------