diff --git a/contracts/hardhat/deploy/01-GlobalOwner.ts b/contracts/hardhat/deploy/01-GlobalOwner.cts similarity index 100% rename from contracts/hardhat/deploy/01-GlobalOwner.ts rename to contracts/hardhat/deploy/01-GlobalOwner.cts diff --git a/contracts/hardhat/deploy/02-GlobalPause.ts b/contracts/hardhat/deploy/02-GlobalPause.cts similarity index 100% rename from contracts/hardhat/deploy/02-GlobalPause.ts rename to contracts/hardhat/deploy/02-GlobalPause.cts diff --git a/contracts/hardhat/deploy/03-GlobalBlacklist.ts b/contracts/hardhat/deploy/03-GlobalBlacklist.cts similarity index 100% rename from contracts/hardhat/deploy/03-GlobalBlacklist.ts rename to contracts/hardhat/deploy/03-GlobalBlacklist.cts diff --git a/contracts/hardhat/deploy/04-APRHistory.ts b/contracts/hardhat/deploy/04-APRHistory.cts similarity index 100% rename from contracts/hardhat/deploy/04-APRHistory.ts rename to contracts/hardhat/deploy/04-APRHistory.cts diff --git a/contracts/hardhat/deploy/05-LDYStaking.ts b/contracts/hardhat/deploy/05-LDYStaking.cts similarity index 100% rename from contracts/hardhat/deploy/05-LDYStaking.ts rename to contracts/hardhat/deploy/05-LDYStaking.cts diff --git a/contracts/hardhat/deploy/06-LUSDC.cts b/contracts/hardhat/deploy/06-LUSDC.cts new file mode 100644 index 00000000..3b7d3e8e --- /dev/null +++ b/contracts/hardhat/deploy/06-LUSDC.cts @@ -0,0 +1,3 @@ +import { deployLToken } from "../lib/deployLToken.cts"; + +module.exports = deployLToken("LUSDC", "USDC"); diff --git a/contracts/hardhat/deploy/06-LUSDC.ts b/contracts/hardhat/deploy/06-LUSDC.ts deleted file mode 100644 index b2208b14..00000000 --- a/contracts/hardhat/deploy/06-LUSDC.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { deployLToken } from "../lib/deployLToken"; - -module.exports = deployLToken("LUSDC", "USDC"); diff --git a/contracts/hardhat/deploy/07-LTokenSignaler.ts b/contracts/hardhat/deploy/07-LTokenSignaler.cts similarity index 100% rename from contracts/hardhat/deploy/07-LTokenSignaler.ts rename to contracts/hardhat/deploy/07-LTokenSignaler.cts diff --git a/contracts/hardhat/deploy/08-Multicall3.ts b/contracts/hardhat/deploy/08-Multicall3.ts deleted file mode 100644 index fbfeaa1b..00000000 --- a/contracts/hardhat/deploy/08-Multicall3.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { type DeployFunction } from "hardhat-deploy/dist/types"; - -module.exports = (async ({ getNamedAccounts, deployments, getChainId }) => { - const { deployer } = await getNamedAccounts(); - const chainId = await getChainId(); - - await deployments.deploy("Multicall3", { - from: deployer, - log: true, - args: [], - waitConfirmations: chainId == "31337" ? 1 : 2, - }); -}) as DeployFunction; - -// Skip deployment if not running on localnet -module.exports.skip = async function ({ getChainId }) { - const chainId = await getChainId(); - return chainId !== "31337"; -} as DeployFunction; diff --git a/contracts/hardhat/deploy/09-PreMining.ts b/contracts/hardhat/deploy/09-PreMining.ts deleted file mode 100644 index 9fd31eb3..00000000 --- a/contracts/hardhat/deploy/09-PreMining.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { type DeployFunction } from "hardhat-deploy/dist/types"; -import { parseUnits } from "viem"; - -module.exports = (async ({ getNamedAccounts, deployments, getChainId }) => { - const { deployer } = await getNamedAccounts(); - const chainId = await getChainId(); - - const lusdc = await deployments.get("LUSDC"); - - await deployments.deploy("PreMining", { - from: deployer, - log: true, - args: [ - lusdc.address, - parseUnits((1_125_000).toString(), 18), - parseUnits((4_000_000).toString(), 6), - 3, - 12, - 6, - ], - waitConfirmations: chainId == "31337" ? 1 : 2, - }); -}) as DeployFunction; - -module.exports.tags = ["PreMining"]; diff --git a/contracts/hardhat/deployments/localhost/APRHistory.json b/contracts/hardhat/deployments/localhost/APRHistory.json index 61664a5f..37e7eb58 100644 --- a/contracts/hardhat/deployments/localhost/APRHistory.json +++ b/contracts/hardhat/deployments/localhost/APRHistory.json @@ -93,7 +93,7 @@ "type": "function" } ], - "transactionHash": "0x0afbd18ec981c763feba629e71ea92d39b3b917d5f9a5c441c2fcc3375a65692", + "transactionHash": "0xafccdf5241d9fbdb5f18618a99997b36d54fb93e9197a8d9c7446d9c8b23c904", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", @@ -101,8 +101,8 @@ "transactionIndex": 0, "gasUsed": "745793", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x82ebda4c29902abc5e8630aa102eebc58b7d32e1f73b54cba2cac13f3ef9f6c9", - "transactionHash": "0x0afbd18ec981c763feba629e71ea92d39b3b917d5f9a5c441c2fcc3375a65692", + "blockHash": "0x6923201a2accb6ebcb48e5ceefe953b100f1dd2db4c05b2693a3730a0b5e9a04", + "transactionHash": "0xafccdf5241d9fbdb5f18618a99997b36d54fb93e9197a8d9c7446d9c8b23c904", "logs": [], "blockNumber": 7, "cumulativeGasUsed": "745793", @@ -111,14 +111,14 @@ }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref1\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref2\",\"type\":\"tuple\"}],\"name\":\"eq\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref\",\"type\":\"tuple\"}],\"name\":\"incrementReference\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Intuition: Each checkpoint in an APR history consists in two data: - the creation timestamp - the APR at that time Given that reads and writes to storage slots are among the most costly operations in Solidity, this library provides a way to store those data on chain in a way that minimizes the number of used storage slots. Instead of storing each checkpoint in a separate storage slot, this library facilitates the packing of up to 4 checkpoints in a single storage slot.Definitions: - Checkpoint: A record of an APR change - Pack: A collection of 4 checkpoints stored in a single storage slot - History: A dynamic array of packs - Reference: A storage pointer to a checkpoint in the APR history - CheckpointData: An in-memory representation of a checkpoint dataLimitation: This library can accommodate APRs only up to 65.536%. This is however sufficient for APR in LToken contract, which is expected to remain below 10%.For further details, see \\\"APRHistory\\\" section of whitepaper.\",\"kind\":\"dev\",\"methods\":{\"eq(APRHistory.Reference,APRHistory.Reference)\":{\"params\":{\"ref1\":\"The first reference to compare.\",\"ref2\":\"The second reference to compare.\"},\"returns\":{\"_0\":\"Whether the two references points to the same checkpoint.\"}},\"getAPR(APRHistory.Pack[] storage)\":{\"params\":{\"self\":\"The history array to read APR from.\"},\"returns\":{\"_0\":\"The latest checkpoint's APR.\"}},\"getDataFromReference(APRHistory.Pack[] storage,APRHistory.Reference)\":{\"params\":{\"ref\":\"The reference of the checkpoint data to extract.\",\"self\":\"The APR history to extract the checkpoint from.\"},\"returns\":{\"_0\":\"The extracted checkpoint's data.\"}},\"getLatestReference(APRHistory.Pack[] storage)\":{\"params\":{\"self\":\"The history to extract the reference from.\"},\"returns\":{\"_0\":\"The reference of the latest checkpoint.\"}},\"incrementReference(APRHistory.Reference)\":{\"params\":{\"ref\":\"The reference to be incremented.\"},\"returns\":{\"_0\":\"The incremented reference.\"}},\"setAPR(APRHistory.Pack[] storage,uint16)\":{\"params\":{\"aprUD7x3\":\"The new APR in UD7x3 format.\",\"self\":\"The array of packs to write the new checkpoint to.\"}}},\"title\":\"APRHistory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"eq(APRHistory.Reference,APRHistory.Reference)\":{\"notice\":\"Compares two checkpoints references.\"},\"getAPR(APRHistory.Pack[] storage)\":{\"notice\":\"Retrieves the APR of the latest checkpoint written in the APR history.\"},\"getDataFromReference(APRHistory.Pack[] storage,APRHistory.Reference)\":{\"notice\":\"Extracts checkpoint data from a given reference and in APR history.\"},\"getLatestReference(APRHistory.Pack[] storage)\":{\"notice\":\"Retrieves the reference to the most recently added checkpoint in the APR history.\"},\"incrementReference(APRHistory.Reference)\":{\"notice\":\"Returns the reference of the checkpoint that should come right after the referenced checkpoint in the APR history.\"},\"setAPR(APRHistory.Pack[] storage,uint16)\":{\"notice\":\"Write a new APR checkpoint at the end of the given history array.\"}},\"notice\":\"This library offers utilities to efficiently maintain on chain, the history of an APR (Annual Percentage Rate). Each entry in this history is called a \\\"checkpoint\\\".\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/libs/APRHistory.sol\":\"APRHistory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/src/libs/APRHistory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title APRHistory\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This library offers utilities to efficiently maintain on chain, the history of\\n * an APR (Annual Percentage Rate). Each entry in this history is called a \\\"checkpoint\\\".\\n *\\n * @dev Intuition:\\n * Each checkpoint in an APR history consists in two data:\\n * - the creation timestamp\\n * - the APR at that time\\n *\\n * Given that reads and writes to storage slots are among the most costly operations in\\n * Solidity, this library provides a way to store those data on chain in a way that\\n * minimizes the number of used storage slots.\\n *\\n * Instead of storing each checkpoint in a separate storage slot, this library\\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\\n *\\n * @dev Definitions:\\n * - Checkpoint: A record of an APR change\\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\\n * - History: A dynamic array of packs\\n * - Reference: A storage pointer to a checkpoint in the APR history\\n * - CheckpointData: An in-memory representation of a checkpoint data\\n *\\n * @dev Limitation: This library can accommodate APRs only up to 65.536%. This is however\\n * sufficient for APR in LToken contract, which is expected to remain below 10%.\\n *\\n * @dev For further details, see \\\"APRHistory\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary APRHistory {\\n /**\\n * @notice Represents data of a checkpoint extracted from the on-chain history.\\n * For on-chain representation see \\\"Pack\\\" struct.\\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\\n * @param timestamp Timestamp of the checkpoint's creation.\\n */\\n struct CheckpointData {\\n uint16 aprUD7x3; // Allows up to 65.536%\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n }\\n\\n /**\\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\\n * @param aprsUD7x3 Array of checkpoints' APRs.\\n * @param timestamps Array of checkpoints' timestamps.\\n * @param cursor Index of the next checkpoint to be written.\\n */\\n struct Pack {\\n uint16[4] aprsUD7x3;\\n uint40[4] timestamps;\\n uint32 cursor;\\n }\\n\\n /**\\n * @notice Represents a storage pointer to a specific checkpoint in the history.\\n * @param packIndex Index of the pack the checkpoint belongs to.\\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\\n */\\n struct Reference {\\n uint256 packIndex;\\n uint32 cursorIndex;\\n }\\n\\n /**\\n * @notice Compares two checkpoints references.\\n * @param ref1 The first reference to compare.\\n * @param ref2 The second reference to compare.\\n * @return Whether the two references points to the same checkpoint.\\n */\\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\\n }\\n\\n /**\\n * @notice Returns the reference of the checkpoint that should come right after the\\n * referenced checkpoint in the APR history.\\n * @param ref The reference to be incremented.\\n * @return The incremented reference.\\n */\\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L1\\\");\\n\\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\\n //\\n // Else, return ref of next slot in current pack\\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\\n }\\n\\n /**\\n * @notice Extracts checkpoint data from a given reference and in APR history.\\n * @param self The APR history to extract the checkpoint from.\\n * @param ref The reference of the checkpoint data to extract.\\n * @return The extracted checkpoint's data.\\n */\\n function getDataFromReference(\\n Pack[] storage self,\\n Reference memory ref\\n ) public view returns (CheckpointData memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L2\\\");\\n\\n // Ensure pack index of the given ref exists in history\\n require(ref.packIndex < self.length, \\\"L3\\\");\\n\\n // Retrieve pack data from history\\n Pack memory pack = self[ref.packIndex];\\n\\n // Ensure cursor index of the given ref has been written\\n require(ref.cursorIndex < pack.cursor, \\\"L4\\\");\\n\\n // Build and return the checkpoint data\\n return\\n CheckpointData({\\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\\n timestamp: pack.timestamps[ref.cursorIndex]\\n });\\n }\\n\\n /**\\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\\n * @param self The history to extract the reference from.\\n * @return The reference of the latest checkpoint.\\n */\\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\\n // Ensure the given history is not empty\\n require(self.length != 0, \\\"L5\\\");\\n\\n // Retrieve latest pack's index and cursor\\n uint256 packIndex = self.length - 1;\\n uint32 packCursor = self[packIndex].cursor;\\n\\n // If this is the first pack ever, ensure it is not empty\\n if (packIndex == 0) require(packCursor != 0, \\\"L6\\\");\\n\\n // If the pack is empty, return ref of previous pack's latest slot\\n if (packCursor == 0) return Reference(packIndex - 1, 3);\\n //\\n // Else, return ref of previous slot in current pack\\n else return Reference(packIndex, packCursor - 1);\\n }\\n\\n /**\\n * @notice Appends a new empty pack to the end of the given APR history array.\\n * @param self The APR history to append an empty to.\\n */\\n function newBlankPack(Pack[] storage self) internal {\\n // If history is not empty, ensure the latest pack is full\\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \\\"L7\\\");\\n\\n // Push a new blank pack to the history array\\n self.push(\\n Pack({\\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\\n cursor: 0\\n })\\n );\\n }\\n\\n /**\\n * @notice Write a new APR checkpoint at the end of the given history array.\\n * @param self The array of packs to write the new checkpoint to.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\\n // Determine the reference where the new checkpoint should be written\\n Reference memory newRef = self.length == 0\\n ? Reference(0, 0)\\n : incrementReference(getLatestReference(self));\\n\\n // If pack to be written doesn't exist yet, push a new blank pack in history\\n if (newRef.packIndex >= self.length) newBlankPack(self);\\n\\n // Retrieve the pack where the new checkpoint will be stored\\n Pack memory pack = self[newRef.packIndex];\\n\\n // Add new checkpoint's data to the pack\\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\\n\\n // Increment the pack's cursor\\n pack.cursor++;\\n\\n // Write the updated pack in storage\\n self[newRef.packIndex] = pack;\\n }\\n\\n /**\\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\\n * @param self The history array to read APR from.\\n * @return The latest checkpoint's APR.\\n */\\n function getAPR(Pack[] storage self) public view returns (uint16) {\\n // Retrieve the latest checkpoint data\\n Reference memory ref = getLatestReference(self);\\n CheckpointData memory data = getDataFromReference(self, ref);\\n\\n // Return the latest checkpoint's APR\\n return data.aprUD7x3;\\n }\\n}\\n\",\"keccak256\":\"0x7954e7130fb127fc8cd81fb852de2df2eda688c0d4ef6cdd9280809cdf2815c3\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x610c8561003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c80630704abfa146100715780634ead0c53146100aa578063593e7d88146100cd5780637c3cb8a614610106578063836b267814610119578063867c775a1461013f575b600080fd5b61008461007f366004610a63565b610161565b604080518251815260209283015163ffffffff1692810192909252015b60405180910390f35b6100bd6100b8366004610aed565b61029a565b60405190151581526020016100a1565b6100e06100db366004610b22565b6102ca565b60408051825161ffff16815260209283015164ffffffffff1692810192909252016100a1565b610084610114366004610b46565b610506565b61012c610127366004610a63565b6105cc565b60405161ffff90911681526020016100a1565b81801561014b57600080fd5b5061015f61015a366004610b62565b6105ef565b005b604080518082019091526000808252602082015281546000036101b05760405162461bcd60e51b81526020600482015260026024820152614c3560f01b60448201526064015b60405180910390fd5b81546000906101c190600190610baf565b905060008382815481106101d7576101d7610bc2565b6000918252602082206002600390920201015463ffffffff169150829003610234578063ffffffff166000036102345760405162461bcd60e51b8152602060048201526002602482015261261b60f11b60448201526064016101a7565b8063ffffffff1660000361026c57604051806040016040528060018461025a9190610baf565b81526003602090910152949350505050565b604051806040016040528083815260200160018361028a9190610bd8565b63ffffffff169052949350505050565b805182516000911480156102c15750816020015163ffffffff16836020015163ffffffff16145b90505b92915050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561031e5760405162461bcd60e51b8152602060048201526002602482015261261960f11b60448201526064016101a7565b82548251106103545760405162461bcd60e51b81526020600482015260026024820152614c3360f01b60448201526064016101a7565b60008383600001518154811061036c5761036c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161039b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116103fa575050509284525050506002919091015463ffffffff9081166020928301526040830151918601519293509081169116106104975760405162461bcd60e51b8152602060048201526002602482015261130d60f21b60448201526064016101a7565b60405180604001604052808260000151856020015163ffffffff16600481106104c2576104c2610bc2565b602002015161ffff1681526020018260200151856020015163ffffffff16600481106104f0576104f0610bc2565b602002015164ffffffffff169052949350505050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561055a5760405162461bcd60e51b81526020600482015260026024820152614c3160f01b60448201526064016101a7565b816020015163ffffffff16600303610598576040518060400160405280836000015160016105889190610bfc565b8152600060209091015292915050565b604051806040016040528083600001518152602001836020015160016105be9190610c0f565b63ffffffff16905292915050565b6000806105d883610161565b905060006105e684836102ca565b51949350505050565b81546000901561060a5761060561011484610161565b61061f565b60408051808201909152600080825260208201525b83548151919250116106345761063483610824565b60008382600001518154811061064c5761064c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161067b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116106da575050509284525050506002919091015463ffffffff9081166020928301528251918501519293508592166004811061075057610750610bc2565b602002019061ffff16908161ffff1681525050428160200151836020015163ffffffff166004811061078457610784610bc2565b64ffffffffff9092166020929092020152604081018051906107a582610c2c565b63ffffffff16905250815184548291869181106107c4576107c4610bc2565b600091825260209091208251600390920201906107e4908290600461092b565b5060208201516107fa90600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550505050565b80541580610844575061083681610161565b6020015163ffffffff166003145b6108755760405162461bcd60e51b81526020600482015260026024820152614c3760f01b60448201526064016101a7565b6040805160e08101825260006060808301828152608080850184905260a0850184905260c085018490529084528451908101855282815260208181018490528186018490529181018390528184015292820181905283546001810185558482529290208151919260030201906108ee908290600461092b565b50602082015161090490600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550565b6001830191839082156109b15791602002820160005b8382111561098157835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610941565b80156109af5782816101000a81549061ffff0219169055600201602081600101049283019260010302610981565b505b506109bd929150610a4e565b5090565b6001830191839082156109b15791602002820160005b83821115610a1d57835183826101000a81548164ffffffffff021916908364ffffffffff16021790555092602001926005016020816004010492830192600103026109d7565b80156109af5782816101000a81549064ffffffffff0219169055600501602081600401049283019260010302610a1d565b5b808211156109bd5760008155600101610a4f565b600060208284031215610a7557600080fd5b5035919050565b600060408284031215610a8e57600080fd5b6040516040810181811067ffffffffffffffff82111715610abf57634e487b7160e01b600052604160045260246000fd5b60405282358152905080602083013563ffffffff81168114610ae057600080fd5b6020919091015292915050565b60008060808385031215610b0057600080fd5b610b0a8484610a7c565b9150610b198460408501610a7c565b90509250929050565b60008060608385031215610b3557600080fd5b82359150610b198460208501610a7c565b600060408284031215610b5857600080fd5b6102c18383610a7c565b60008060408385031215610b7557600080fd5b82359150602083013561ffff81168114610b8e57600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102c4576102c4610b99565b634e487b7160e01b600052603260045260246000fd5b63ffffffff828116828216039080821115610bf557610bf5610b99565b5092915050565b808201808211156102c4576102c4610b99565b63ffffffff818116838216019080821115610bf557610bf5610b99565b600063ffffffff808316818103610c4557610c45610b99565b600101939250505056fea26469706673582212200e329fe9da7eb31b10be3b7e59dda8f4c3d79b2336a8ccac62e5aedaa27a7a3f64736f6c63430008120033", - "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c80630704abfa146100715780634ead0c53146100aa578063593e7d88146100cd5780637c3cb8a614610106578063836b267814610119578063867c775a1461013f575b600080fd5b61008461007f366004610a63565b610161565b604080518251815260209283015163ffffffff1692810192909252015b60405180910390f35b6100bd6100b8366004610aed565b61029a565b60405190151581526020016100a1565b6100e06100db366004610b22565b6102ca565b60408051825161ffff16815260209283015164ffffffffff1692810192909252016100a1565b610084610114366004610b46565b610506565b61012c610127366004610a63565b6105cc565b60405161ffff90911681526020016100a1565b81801561014b57600080fd5b5061015f61015a366004610b62565b6105ef565b005b604080518082019091526000808252602082015281546000036101b05760405162461bcd60e51b81526020600482015260026024820152614c3560f01b60448201526064015b60405180910390fd5b81546000906101c190600190610baf565b905060008382815481106101d7576101d7610bc2565b6000918252602082206002600390920201015463ffffffff169150829003610234578063ffffffff166000036102345760405162461bcd60e51b8152602060048201526002602482015261261b60f11b60448201526064016101a7565b8063ffffffff1660000361026c57604051806040016040528060018461025a9190610baf565b81526003602090910152949350505050565b604051806040016040528083815260200160018361028a9190610bd8565b63ffffffff169052949350505050565b805182516000911480156102c15750816020015163ffffffff16836020015163ffffffff16145b90505b92915050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561031e5760405162461bcd60e51b8152602060048201526002602482015261261960f11b60448201526064016101a7565b82548251106103545760405162461bcd60e51b81526020600482015260026024820152614c3360f01b60448201526064016101a7565b60008383600001518154811061036c5761036c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161039b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116103fa575050509284525050506002919091015463ffffffff9081166020928301526040830151918601519293509081169116106104975760405162461bcd60e51b8152602060048201526002602482015261130d60f21b60448201526064016101a7565b60405180604001604052808260000151856020015163ffffffff16600481106104c2576104c2610bc2565b602002015161ffff1681526020018260200151856020015163ffffffff16600481106104f0576104f0610bc2565b602002015164ffffffffff169052949350505050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561055a5760405162461bcd60e51b81526020600482015260026024820152614c3160f01b60448201526064016101a7565b816020015163ffffffff16600303610598576040518060400160405280836000015160016105889190610bfc565b8152600060209091015292915050565b604051806040016040528083600001518152602001836020015160016105be9190610c0f565b63ffffffff16905292915050565b6000806105d883610161565b905060006105e684836102ca565b51949350505050565b81546000901561060a5761060561011484610161565b61061f565b60408051808201909152600080825260208201525b83548151919250116106345761063483610824565b60008382600001518154811061064c5761064c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161067b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116106da575050509284525050506002919091015463ffffffff9081166020928301528251918501519293508592166004811061075057610750610bc2565b602002019061ffff16908161ffff1681525050428160200151836020015163ffffffff166004811061078457610784610bc2565b64ffffffffff9092166020929092020152604081018051906107a582610c2c565b63ffffffff16905250815184548291869181106107c4576107c4610bc2565b600091825260209091208251600390920201906107e4908290600461092b565b5060208201516107fa90600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550505050565b80541580610844575061083681610161565b6020015163ffffffff166003145b6108755760405162461bcd60e51b81526020600482015260026024820152614c3760f01b60448201526064016101a7565b6040805160e08101825260006060808301828152608080850184905260a0850184905260c085018490529084528451908101855282815260208181018490528186018490529181018390528184015292820181905283546001810185558482529290208151919260030201906108ee908290600461092b565b50602082015161090490600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550565b6001830191839082156109b15791602002820160005b8382111561098157835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610941565b80156109af5782816101000a81549061ffff0219169055600201602081600101049283019260010302610981565b505b506109bd929150610a4e565b5090565b6001830191839082156109b15791602002820160005b83821115610a1d57835183826101000a81548164ffffffffff021916908364ffffffffff16021790555092602001926005016020816004010492830192600103026109d7565b80156109af5782816101000a81549064ffffffffff0219169055600501602081600401049283019260010302610a1d565b5b808211156109bd5760008155600101610a4f565b600060208284031215610a7557600080fd5b5035919050565b600060408284031215610a8e57600080fd5b6040516040810181811067ffffffffffffffff82111715610abf57634e487b7160e01b600052604160045260246000fd5b60405282358152905080602083013563ffffffff81168114610ae057600080fd5b6020919091015292915050565b60008060808385031215610b0057600080fd5b610b0a8484610a7c565b9150610b198460408501610a7c565b90509250929050565b60008060608385031215610b3557600080fd5b82359150610b198460208501610a7c565b600060408284031215610b5857600080fd5b6102c18383610a7c565b60008060408385031215610b7557600080fd5b82359150602083013561ffff81168114610b8e57600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102c4576102c4610b99565b634e487b7160e01b600052603260045260246000fd5b63ffffffff828116828216039080821115610bf557610bf5610b99565b5092915050565b808201808211156102c4576102c4610b99565b63ffffffff818116838216019080821115610bf557610bf5610b99565b600063ffffffff808316818103610c4557610c45610b99565b600101939250505056fea26469706673582212200e329fe9da7eb31b10be3b7e59dda8f4c3d79b2336a8ccac62e5aedaa27a7a3f64736f6c63430008120033", + "solcInputHash": "1c94255f5edec71501da736e9b19ae5f", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref1\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref2\",\"type\":\"tuple\"}],\"name\":\"eq\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"ref\",\"type\":\"tuple\"}],\"name\":\"incrementReference\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"packIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"cursorIndex\",\"type\":\"uint32\"}],\"internalType\":\"struct APRHistory.Reference\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Intuition: Each checkpoint in an APR history consists of two data: - the creation timestamp - the APR at that time Given that reading and writing to storage slots are among the most costly operations in Solidity, this library provides a way to store those data in a way that minimizes the number of used storage slots. Instead of storing each checkpoint in a separate storage slot, this library facilitates the packing of up to 4 checkpoints in a single storage slot.Definitions: - Checkpoint: A record of an APR change - Pack: A collection of 4 checkpoints stored in a single storage slot - History: A dynamic array of packs - Reference: A storage pointer to a checkpoint in the APR history - CheckpointData: An in-memory representation of a checkpoint dataValue limitation: This library can accommodate APRs only up to 65.536%. This is however sufficient for APR in LToken contract, which is expected to remain below 10%.For further details, see \\\"APRHistory\\\" section of whitepaper.\",\"kind\":\"dev\",\"methods\":{\"eq(APRHistory.Reference,APRHistory.Reference)\":{\"params\":{\"ref1\":\"The first reference to compare.\",\"ref2\":\"The second reference to compare.\"},\"returns\":{\"_0\":\"Whether the two references points to the same checkpoint.\"}},\"getAPR(APRHistory.Pack[] storage)\":{\"params\":{\"self\":\"The history array to read APR from.\"},\"returns\":{\"_0\":\"The latest checkpoint's APR.\"}},\"getDataFromReference(APRHistory.Pack[] storage,APRHistory.Reference)\":{\"params\":{\"ref\":\"The reference of the checkpoint data to extract.\",\"self\":\"The APR history to extract the checkpoint from.\"},\"returns\":{\"_0\":\"The extracted checkpoint's data.\"}},\"getLatestReference(APRHistory.Pack[] storage)\":{\"params\":{\"self\":\"The history to extract the reference from.\"},\"returns\":{\"_0\":\"The reference of the latest checkpoint.\"}},\"incrementReference(APRHistory.Reference)\":{\"params\":{\"ref\":\"The reference to be incremented.\"},\"returns\":{\"_0\":\"The incremented reference.\"}},\"setAPR(APRHistory.Pack[] storage,uint16)\":{\"params\":{\"aprUD7x3\":\"The new APR in UD7x3 format.\",\"self\":\"The array of packs to write the new checkpoint to.\"}}},\"title\":\"APRHistory\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"eq(APRHistory.Reference,APRHistory.Reference)\":{\"notice\":\"Compares two checkpoints references.\"},\"getAPR(APRHistory.Pack[] storage)\":{\"notice\":\"Retrieves the APR of the latest checkpoint written in the APR history.\"},\"getDataFromReference(APRHistory.Pack[] storage,APRHistory.Reference)\":{\"notice\":\"Extracts checkpoint data from a given reference and in APR history.\"},\"getLatestReference(APRHistory.Pack[] storage)\":{\"notice\":\"Retrieves the reference to the most recently added checkpoint in the APR history.\"},\"incrementReference(APRHistory.Reference)\":{\"notice\":\"Returns the reference of the checkpoint that should come right after the referenced checkpoint in the APR history.\"},\"setAPR(APRHistory.Pack[] storage,uint16)\":{\"notice\":\"Write a new APR checkpoint at the end of the given history array.\"}},\"notice\":\"This library offers utilities to efficiently maintain the history of an on-chain APR (Annual Percentage Rate) state. Each entry in this history is called a \\\"checkpoint\\\".\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/libs/APRHistory.sol\":\"APRHistory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/src/libs/APRHistory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/**\\n * @title APRHistory\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This library offers utilities to efficiently maintain the history of an\\n * on-chain APR (Annual Percentage Rate) state. Each entry in this history is called\\n * a \\\"checkpoint\\\".\\n *\\n * @dev Intuition:\\n * Each checkpoint in an APR history consists of two data:\\n * - the creation timestamp\\n * - the APR at that time\\n *\\n * Given that reading and writing to storage slots are among the most costly operations\\n * in Solidity, this library provides a way to store those data in a way that minimizes\\n * the number of used storage slots.\\n *\\n * Instead of storing each checkpoint in a separate storage slot, this library\\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\\n *\\n * @dev Definitions:\\n * - Checkpoint: A record of an APR change\\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\\n * - History: A dynamic array of packs\\n * - Reference: A storage pointer to a checkpoint in the APR history\\n * - CheckpointData: An in-memory representation of a checkpoint data\\n *\\n * @dev Value limitation:\\n * This library can accommodate APRs only up to 65.536%. This is however sufficient for\\n * APR in LToken contract, which is expected to remain below 10%.\\n *\\n * @dev For further details, see \\\"APRHistory\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary APRHistory {\\n /**\\n * @notice Represents data of a checkpoint extracted from the on-chain history.\\n * For on-chain representation see \\\"Pack\\\" struct.\\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\\n * @param timestamp Timestamp of the checkpoint's creation.\\n */\\n struct CheckpointData {\\n uint16 aprUD7x3; // Allows up to 65.536%\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n }\\n\\n /**\\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\\n * @param aprsUD7x3 Array of checkpoints' APRs.\\n * @param timestamps Array of checkpoints' timestamps.\\n * @param cursor Index of the next checkpoint to be written.\\n */\\n struct Pack {\\n uint16[4] aprsUD7x3;\\n uint40[4] timestamps;\\n uint32 cursor;\\n }\\n\\n /**\\n * @notice Represents a storage pointer to a specific checkpoint in the history.\\n * @param packIndex Index of the pack the checkpoint belongs to.\\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\\n */\\n struct Reference {\\n uint256 packIndex;\\n uint32 cursorIndex;\\n }\\n\\n /**\\n * @notice Compares two checkpoints references.\\n * @param ref1 The first reference to compare.\\n * @param ref2 The second reference to compare.\\n * @return Whether the two references points to the same checkpoint.\\n */\\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\\n }\\n\\n /**\\n * @notice Returns the reference of the checkpoint that should come right after the\\n * referenced checkpoint in the APR history.\\n * @param ref The reference to be incremented.\\n * @return The incremented reference.\\n */\\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L1\\\");\\n\\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\\n //\\n // Else, return ref of next slot in current pack\\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\\n }\\n\\n /**\\n * @notice Extracts checkpoint data from a given reference and in APR history.\\n * @param self The APR history to extract the checkpoint from.\\n * @param ref The reference of the checkpoint data to extract.\\n * @return The extracted checkpoint's data.\\n */\\n function getDataFromReference(\\n Pack[] storage self,\\n Reference memory ref\\n ) public view returns (CheckpointData memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L2\\\");\\n\\n // Ensure pack index of the given ref exists in history\\n require(ref.packIndex < self.length, \\\"L3\\\");\\n\\n // Retrieve pack data from history\\n Pack memory pack = self[ref.packIndex];\\n\\n // Ensure cursor index of the given ref has been written\\n require(ref.cursorIndex < pack.cursor, \\\"L4\\\");\\n\\n // Build and return the checkpoint data\\n return\\n CheckpointData({\\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\\n timestamp: pack.timestamps[ref.cursorIndex]\\n });\\n }\\n\\n /**\\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\\n * @param self The history to extract the reference from.\\n * @return The reference of the latest checkpoint.\\n */\\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\\n // Ensure the given history is not empty\\n require(self.length != 0, \\\"L5\\\");\\n\\n // Retrieve latest pack's index and cursor\\n uint256 packIndex = self.length - 1;\\n uint32 packCursor = self[packIndex].cursor;\\n\\n // If this is the first pack ever, ensure it is not empty\\n if (packIndex == 0) require(packCursor != 0, \\\"L6\\\");\\n\\n // If the pack is empty, return ref of previous pack's latest slot\\n if (packCursor == 0) return Reference(packIndex - 1, 3);\\n //\\n // Else, return ref of previous slot in current pack\\n else return Reference(packIndex, packCursor - 1);\\n }\\n\\n /**\\n * @notice Appends a new empty pack to the end of the given APR history array.\\n * @param self The APR history to append an empty to.\\n */\\n function newBlankPack(Pack[] storage self) internal {\\n // If history is not empty, ensure the latest pack is full\\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \\\"L7\\\");\\n\\n // Push a new blank pack to the history array\\n self.push(\\n Pack({\\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\\n cursor: 0\\n })\\n );\\n }\\n\\n /**\\n * @notice Write a new APR checkpoint at the end of the given history array.\\n * @param self The array of packs to write the new checkpoint to.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\\n // Determine the reference where the new checkpoint should be written\\n Reference memory newRef = self.length == 0\\n ? Reference(0, 0)\\n : incrementReference(getLatestReference(self));\\n\\n // If pack to be written doesn't exist yet, push a new blank pack in history\\n if (newRef.packIndex >= self.length) newBlankPack(self);\\n\\n // Retrieve the pack where the new checkpoint will be stored\\n Pack memory pack = self[newRef.packIndex];\\n\\n // Add new checkpoint's data to the pack\\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\\n\\n // Increment the pack's cursor\\n pack.cursor++;\\n\\n // Write the updated pack in storage\\n self[newRef.packIndex] = pack;\\n }\\n\\n /**\\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\\n * @param self The history array to read APR from.\\n * @return The latest checkpoint's APR.\\n */\\n function getAPR(Pack[] storage self) public view returns (uint16) {\\n // Retrieve the latest checkpoint data\\n Reference memory ref = getLatestReference(self);\\n CheckpointData memory data = getDataFromReference(self, ref);\\n\\n // Return the latest checkpoint's APR\\n return data.aprUD7x3;\\n }\\n}\\n\",\"keccak256\":\"0x0b3d02a33c5e5be03cefc5192439def2efa43be664c372e83f309be34fd476b7\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x610c8561003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c80630704abfa146100715780634ead0c53146100aa578063593e7d88146100cd5780637c3cb8a614610106578063836b267814610119578063867c775a1461013f575b600080fd5b61008461007f366004610a63565b610161565b604080518251815260209283015163ffffffff1692810192909252015b60405180910390f35b6100bd6100b8366004610aed565b61029a565b60405190151581526020016100a1565b6100e06100db366004610b22565b6102ca565b60408051825161ffff16815260209283015164ffffffffff1692810192909252016100a1565b610084610114366004610b46565b610506565b61012c610127366004610a63565b6105cc565b60405161ffff90911681526020016100a1565b81801561014b57600080fd5b5061015f61015a366004610b62565b6105ef565b005b604080518082019091526000808252602082015281546000036101b05760405162461bcd60e51b81526020600482015260026024820152614c3560f01b60448201526064015b60405180910390fd5b81546000906101c190600190610baf565b905060008382815481106101d7576101d7610bc2565b6000918252602082206002600390920201015463ffffffff169150829003610234578063ffffffff166000036102345760405162461bcd60e51b8152602060048201526002602482015261261b60f11b60448201526064016101a7565b8063ffffffff1660000361026c57604051806040016040528060018461025a9190610baf565b81526003602090910152949350505050565b604051806040016040528083815260200160018361028a9190610bd8565b63ffffffff169052949350505050565b805182516000911480156102c15750816020015163ffffffff16836020015163ffffffff16145b90505b92915050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561031e5760405162461bcd60e51b8152602060048201526002602482015261261960f11b60448201526064016101a7565b82548251106103545760405162461bcd60e51b81526020600482015260026024820152614c3360f01b60448201526064016101a7565b60008383600001518154811061036c5761036c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161039b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116103fa575050509284525050506002919091015463ffffffff9081166020928301526040830151918601519293509081169116106104975760405162461bcd60e51b8152602060048201526002602482015261130d60f21b60448201526064016101a7565b60405180604001604052808260000151856020015163ffffffff16600481106104c2576104c2610bc2565b602002015161ffff1681526020018260200151856020015163ffffffff16600481106104f0576104f0610bc2565b602002015164ffffffffff169052949350505050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561055a5760405162461bcd60e51b81526020600482015260026024820152614c3160f01b60448201526064016101a7565b816020015163ffffffff16600303610598576040518060400160405280836000015160016105889190610bfc565b8152600060209091015292915050565b604051806040016040528083600001518152602001836020015160016105be9190610c0f565b63ffffffff16905292915050565b6000806105d883610161565b905060006105e684836102ca565b51949350505050565b81546000901561060a5761060561011484610161565b61061f565b60408051808201909152600080825260208201525b83548151919250116106345761063483610824565b60008382600001518154811061064c5761064c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161067b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116106da575050509284525050506002919091015463ffffffff9081166020928301528251918501519293508592166004811061075057610750610bc2565b602002019061ffff16908161ffff1681525050428160200151836020015163ffffffff166004811061078457610784610bc2565b64ffffffffff9092166020929092020152604081018051906107a582610c2c565b63ffffffff16905250815184548291869181106107c4576107c4610bc2565b600091825260209091208251600390920201906107e4908290600461092b565b5060208201516107fa90600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550505050565b80541580610844575061083681610161565b6020015163ffffffff166003145b6108755760405162461bcd60e51b81526020600482015260026024820152614c3760f01b60448201526064016101a7565b6040805160e08101825260006060808301828152608080850184905260a0850184905260c085018490529084528451908101855282815260208181018490528186018490529181018390528184015292820181905283546001810185558482529290208151919260030201906108ee908290600461092b565b50602082015161090490600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550565b6001830191839082156109b15791602002820160005b8382111561098157835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610941565b80156109af5782816101000a81549061ffff0219169055600201602081600101049283019260010302610981565b505b506109bd929150610a4e565b5090565b6001830191839082156109b15791602002820160005b83821115610a1d57835183826101000a81548164ffffffffff021916908364ffffffffff16021790555092602001926005016020816004010492830192600103026109d7565b80156109af5782816101000a81549064ffffffffff0219169055600501602081600401049283019260010302610a1d565b5b808211156109bd5760008155600101610a4f565b600060208284031215610a7557600080fd5b5035919050565b600060408284031215610a8e57600080fd5b6040516040810181811067ffffffffffffffff82111715610abf57634e487b7160e01b600052604160045260246000fd5b60405282358152905080602083013563ffffffff81168114610ae057600080fd5b6020919091015292915050565b60008060808385031215610b0057600080fd5b610b0a8484610a7c565b9150610b198460408501610a7c565b90509250929050565b60008060608385031215610b3557600080fd5b82359150610b198460208501610a7c565b600060408284031215610b5857600080fd5b6102c18383610a7c565b60008060408385031215610b7557600080fd5b82359150602083013561ffff81168114610b8e57600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102c4576102c4610b99565b634e487b7160e01b600052603260045260246000fd5b63ffffffff828116828216039080821115610bf557610bf5610b99565b5092915050565b808201808211156102c4576102c4610b99565b63ffffffff818116838216019080821115610bf557610bf5610b99565b600063ffffffff808316818103610c4557610c45610b99565b600101939250505056fea264697066735822122037273d18074a95e25b4ee897634daa0209a4e04e6077ddaa99b1038cb31b2bc164736f6c63430008120033", + "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361061006c5760003560e01c80630704abfa146100715780634ead0c53146100aa578063593e7d88146100cd5780637c3cb8a614610106578063836b267814610119578063867c775a1461013f575b600080fd5b61008461007f366004610a63565b610161565b604080518251815260209283015163ffffffff1692810192909252015b60405180910390f35b6100bd6100b8366004610aed565b61029a565b60405190151581526020016100a1565b6100e06100db366004610b22565b6102ca565b60408051825161ffff16815260209283015164ffffffffff1692810192909252016100a1565b610084610114366004610b46565b610506565b61012c610127366004610a63565b6105cc565b60405161ffff90911681526020016100a1565b81801561014b57600080fd5b5061015f61015a366004610b62565b6105ef565b005b604080518082019091526000808252602082015281546000036101b05760405162461bcd60e51b81526020600482015260026024820152614c3560f01b60448201526064015b60405180910390fd5b81546000906101c190600190610baf565b905060008382815481106101d7576101d7610bc2565b6000918252602082206002600390920201015463ffffffff169150829003610234578063ffffffff166000036102345760405162461bcd60e51b8152602060048201526002602482015261261b60f11b60448201526064016101a7565b8063ffffffff1660000361026c57604051806040016040528060018461025a9190610baf565b81526003602090910152949350505050565b604051806040016040528083815260200160018361028a9190610bd8565b63ffffffff169052949350505050565b805182516000911480156102c15750816020015163ffffffff16836020015163ffffffff16145b90505b92915050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561031e5760405162461bcd60e51b8152602060048201526002602482015261261960f11b60448201526064016101a7565b82548251106103545760405162461bcd60e51b81526020600482015260026024820152614c3360f01b60448201526064016101a7565b60008383600001518154811061036c5761036c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161039b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116103fa575050509284525050506002919091015463ffffffff9081166020928301526040830151918601519293509081169116106104975760405162461bcd60e51b8152602060048201526002602482015261130d60f21b60448201526064016101a7565b60405180604001604052808260000151856020015163ffffffff16600481106104c2576104c2610bc2565b602002015161ffff1681526020018260200151856020015163ffffffff16600481106104f0576104f0610bc2565b602002015164ffffffffff169052949350505050565b60408051808201909152600080825260208201526003826020015163ffffffff16111561055a5760405162461bcd60e51b81526020600482015260026024820152614c3160f01b60448201526064016101a7565b816020015163ffffffff16600303610598576040518060400160405280836000015160016105889190610bfc565b8152600060209091015292915050565b604051806040016040528083600001518152602001836020015160016105be9190610c0f565b63ffffffff16905292915050565b6000806105d883610161565b905060006105e684836102ca565b51949350505050565b81546000901561060a5761060561011484610161565b61061f565b60408051808201909152600080825260208201525b83548151919250116106345761063483610824565b60008382600001518154811061064c5761064c610bc2565b600091825260209091206040805160e08101909152916003020181606081018260048282826020028201916000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161067b57505050928452505060408051608081019182905260209093019291506001840190600490826000855b82829054906101000a900464ffffffffff1664ffffffffff16815260200190600501906020826004010492830192600103820291508084116106da575050509284525050506002919091015463ffffffff9081166020928301528251918501519293508592166004811061075057610750610bc2565b602002019061ffff16908161ffff1681525050428160200151836020015163ffffffff166004811061078457610784610bc2565b64ffffffffff9092166020929092020152604081018051906107a582610c2c565b63ffffffff16905250815184548291869181106107c4576107c4610bc2565b600091825260209091208251600390920201906107e4908290600461092b565b5060208201516107fa90600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550505050565b80541580610844575061083681610161565b6020015163ffffffff166003145b6108755760405162461bcd60e51b81526020600482015260026024820152614c3760f01b60448201526064016101a7565b6040805160e08101825260006060808301828152608080850184905260a0850184905260c085018490529084528451908101855282815260208181018490528186018490529181018390528184015292820181905283546001810185558482529290208151919260030201906108ee908290600461092b565b50602082015161090490600183019060046109c1565b50604091909101516002909101805463ffffffff191663ffffffff90921691909117905550565b6001830191839082156109b15791602002820160005b8382111561098157835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610941565b80156109af5782816101000a81549061ffff0219169055600201602081600101049283019260010302610981565b505b506109bd929150610a4e565b5090565b6001830191839082156109b15791602002820160005b83821115610a1d57835183826101000a81548164ffffffffff021916908364ffffffffff16021790555092602001926005016020816004010492830192600103026109d7565b80156109af5782816101000a81549064ffffffffff0219169055600501602081600401049283019260010302610a1d565b5b808211156109bd5760008155600101610a4f565b600060208284031215610a7557600080fd5b5035919050565b600060408284031215610a8e57600080fd5b6040516040810181811067ffffffffffffffff82111715610abf57634e487b7160e01b600052604160045260246000fd5b60405282358152905080602083013563ffffffff81168114610ae057600080fd5b6020919091015292915050565b60008060808385031215610b0057600080fd5b610b0a8484610a7c565b9150610b198460408501610a7c565b90509250929050565b60008060608385031215610b3557600080fd5b82359150610b198460208501610a7c565b600060408284031215610b5857600080fd5b6102c18383610a7c565b60008060408385031215610b7557600080fd5b82359150602083013561ffff81168114610b8e57600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156102c4576102c4610b99565b634e487b7160e01b600052603260045260246000fd5b63ffffffff828116828216039080821115610bf557610bf5610b99565b5092915050565b808201808211156102c4576102c4610b99565b63ffffffff818116838216019080821115610bf557610bf5610b99565b600063ffffffff808316818103610c4557610c45610b99565b600101939250505056fea264697066735822122037273d18074a95e25b4ee897634daa0209a4e04e6077ddaa99b1038cb31b2bc164736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", - "details": "Intuition: Each checkpoint in an APR history consists in two data: - the creation timestamp - the APR at that time Given that reads and writes to storage slots are among the most costly operations in Solidity, this library provides a way to store those data on chain in a way that minimizes the number of used storage slots. Instead of storing each checkpoint in a separate storage slot, this library facilitates the packing of up to 4 checkpoints in a single storage slot.Definitions: - Checkpoint: A record of an APR change - Pack: A collection of 4 checkpoints stored in a single storage slot - History: A dynamic array of packs - Reference: A storage pointer to a checkpoint in the APR history - CheckpointData: An in-memory representation of a checkpoint dataLimitation: This library can accommodate APRs only up to 65.536%. This is however sufficient for APR in LToken contract, which is expected to remain below 10%.For further details, see \"APRHistory\" section of whitepaper.", + "details": "Intuition: Each checkpoint in an APR history consists of two data: - the creation timestamp - the APR at that time Given that reading and writing to storage slots are among the most costly operations in Solidity, this library provides a way to store those data in a way that minimizes the number of used storage slots. Instead of storing each checkpoint in a separate storage slot, this library facilitates the packing of up to 4 checkpoints in a single storage slot.Definitions: - Checkpoint: A record of an APR change - Pack: A collection of 4 checkpoints stored in a single storage slot - History: A dynamic array of packs - Reference: A storage pointer to a checkpoint in the APR history - CheckpointData: An in-memory representation of a checkpoint dataValue limitation: This library can accommodate APRs only up to 65.536%. This is however sufficient for APR in LToken contract, which is expected to remain below 10%.For further details, see \"APRHistory\" section of whitepaper.", "kind": "dev", "methods": { "eq(APRHistory.Reference,APRHistory.Reference)": { @@ -195,7 +195,7 @@ "notice": "Write a new APR checkpoint at the end of the given history array." } }, - "notice": "This library offers utilities to efficiently maintain on chain, the history of an APR (Annual Percentage Rate). Each entry in this history is called a \"checkpoint\".", + "notice": "This library offers utilities to efficiently maintain the history of an on-chain APR (Annual Percentage Rate) state. Each entry in this history is called a \"checkpoint\".", "version": 1 }, "storageLayout": { diff --git a/contracts/hardhat/deployments/localhost/GlobalBlacklist.json b/contracts/hardhat/deployments/localhost/GlobalBlacklist.json index bf4e48ce..7195c4c8 100644 --- a/contracts/hardhat/deployments/localhost/GlobalBlacklist.json +++ b/contracts/hardhat/deployments/localhost/GlobalBlacklist.json @@ -54,6 +54,19 @@ "stateMutability": "payable", "type": "receive" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Blacklisted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -86,6 +99,19 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unblacklisted", + "type": "event" + }, { "inputs": [ { @@ -259,7 +285,7 @@ "transactionIndex": 0, "gasUsed": "332581", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000002000000000240000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000080400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae", + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362", "transactionHash": "0xaee795c43b7a10f17952d609bd43b93152e955c2fa1993abf9cfc84351844bd5", "logs": [ { @@ -273,7 +299,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae" + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362" }, { "transactionIndex": 0, @@ -285,7 +311,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae" + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362" } ], "blockNumber": 6, diff --git a/contracts/hardhat/deployments/localhost/GlobalBlacklist_Implementation.json b/contracts/hardhat/deployments/localhost/GlobalBlacklist_Implementation.json index fad04e1a..5773d778 100644 --- a/contracts/hardhat/deployments/localhost/GlobalBlacklist_Implementation.json +++ b/contracts/hardhat/deployments/localhost/GlobalBlacklist_Implementation.json @@ -38,6 +38,19 @@ "name": "BeaconUpgraded", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Blacklisted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -70,6 +83,19 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unblacklisted", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -232,41 +258,41 @@ "type": "function" } ], - "transactionHash": "0x2cc9b750f647075537f8d454381eb8e5602d68ca7d1c5ca3ac21dde1282c30da", + "transactionHash": "0x0e8fce9014801f5c0a3a9fff8eaa8ffda2b20b92e0c2cc2243cb71ae9207af3a", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", "transactionIndex": 0, - "gasUsed": "914500", + "gasUsed": "936792", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000020000000000000000000000000000000000000000000000000000000000001000000000100000000000000", - "blockHash": "0x6517e3e8b2540d88ab40f6375e36cec63cb16912afd72bfd4d09b51a755071e1", - "transactionHash": "0x2cc9b750f647075537f8d454381eb8e5602d68ca7d1c5ca3ac21dde1282c30da", + "blockHash": "0xa501c4b83e21a58ca4eee657537a7653999efc0062fefc2bbcba7cc1a35b59fc", + "transactionHash": "0x0e8fce9014801f5c0a3a9fff8eaa8ffda2b20b92e0c2cc2243cb71ae9207af3a", "logs": [ { "transactionIndex": 0, "blockNumber": 5, - "transactionHash": "0x2cc9b750f647075537f8d454381eb8e5602d68ca7d1c5ca3ac21dde1282c30da", + "transactionHash": "0x0e8fce9014801f5c0a3a9fff8eaa8ffda2b20b92e0c2cc2243cb71ae9207af3a", "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0x6517e3e8b2540d88ab40f6375e36cec63cb16912afd72bfd4d09b51a755071e1" + "blockHash": "0xa501c4b83e21a58ca4eee657537a7653999efc0062fefc2bbcba7cc1a35b59fc" } ], "blockNumber": 5, - "cumulativeGasUsed": "914500", + "cumulativeGasUsed": "936792", "status": 1, "byzantium": true }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"blacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isBlacklisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers and getter functions to easily check against this global blacklist.For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"blacklist(address)\":{\"params\":{\"account\":\"The account's address to be blacklisted.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalOwner_\":\"The address of the GlobalOwner contract.\"}},\"isBlacklisted(address)\":{\"params\":{\"account\":\"Address of the account to check.\"},\"returns\":{\"_0\":\"'true' if the account is blacklisted, 'false' otherwise\"}},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"unBlacklist(address)\":{\"params\":{\"account\":\"The account's address to be un-blacklisted.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"stateVariables\":{\"_list\":{\"details\":\"This mapping is made private and isBlacklisted() should be used instead.This helps saving gas in some scenario. See isBlacklisted() documentation for more details.\"}},\"title\":\"GlobalBlacklist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"blacklist(address)\":{\"notice\":\"Adds a given account to the blacklist.\"},\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"isBlacklisted(address)\":{\"notice\":\"Checks whether a given account is blacklisted.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"unBlacklist(address)\":{\"notice\":\"Removes a given account from the blacklist.\"}},\"notice\":\"Maintains a global mapping of blacklisted accounts on-chain. All contracts within the Ledgity Yield codebase reference this mapping to prevent access by blacklisted accounts.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalBlacklist.sol\":\"GlobalBlacklist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalBlacklist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalBlacklist\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global mapping of blacklisted accounts on-chain. All contracts\\n * within the Ledgity Yield codebase reference this mapping to prevent access by\\n * blacklisted accounts.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\\n * and getter functions to easily check against this global blacklist.\\n *\\n * @dev For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Mapping of accounts to their blacklist status.\\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\\n */\\n mapping(address => bool) private _list;\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Adds a given account to the blacklist.\\n * @param account The account's address to be blacklisted.\\n */\\n function blacklist(address account) external onlyOwner {\\n require(account != address(0), \\\"L20\\\");\\n _list[account] = true;\\n }\\n\\n /**\\n * @notice Removes a given account from the blacklist.\\n * @param account The account's address to be un-blacklisted.\\n */\\n function unBlacklist(address account) external onlyOwner {\\n _list[account] = false;\\n }\\n\\n /**\\n * @notice Checks whether a given account is blacklisted.\\n * @param account Address of the account to check.\\n * @return 'true' if the account is blacklisted, 'false' otherwise\\n */\\n function isBlacklisted(address account) external view returns (bool) {\\n // Gas optimization: Avoid accessing storage if account is the zero address\\n // (e.g, during a mint or a burn of tokens)\\n if (account == address(0)) return false;\\n\\n // Else, return current account's blacklist status\\n return _list[account];\\n }\\n}\\n\",\"keccak256\":\"0x8e4d4072f74f9d683bf0b54d76fa08201cf507eb791d217178a0ee9d6aaa3ddf\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x59c14d38e9e96d4f60cf2fd626c56e23928fce85107ac8d603dfdb90c9d81ec4\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610f1d610118600039600081816102410152818161028a015281816103290152818161036901526103fc0152610f1d6000f3fe60806040526004361061009c5760003560e01c80638da5cb5b116100645780638da5cb5b14610133578063c4d66de814610160578063f2fde38b14610180578063f762e734146101a0578063f9f92be4146101be578063fe575a87146101de57600080fd5b80631a895266146100a15780633659cfe6146100c35780634f1ef286146100e357806352d1902d146100f6578063715018a61461011e575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610c1d565b61020e565b005b3480156100cf57600080fd5b506100c16100de366004610c1d565b610237565b6100c16100f1366004610c50565b61031f565b34801561010257600080fd5b5061010b6103ef565b6040519081526020015b60405180910390f35b34801561012a57600080fd5b506100c16104a2565b34801561013f57600080fd5b506101486104d8565b6040516001600160a01b039091168152602001610115565b34801561016c57600080fd5b506100c161017b366004610c1d565b61054b565b34801561018c57600080fd5b506100c161019b366004610c1d565b610665565b3480156101ac57600080fd5b5060c9546001600160a01b0316610148565b3480156101ca57600080fd5b506100c16101d9366004610c1d565b61069a565b3480156101ea57600080fd5b506101fe6101f9366004610c1d565b610702565b6040519015158152602001610115565b610216610739565b6001600160a01b0316600090815260fc60205260409020805460ff19169055565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102885760405162461bcd60e51b815260040161027f90610d14565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166102d1600080516020610ea1833981519152546001600160a01b031690565b6001600160a01b0316146102f75760405162461bcd60e51b815260040161027f90610d60565b6103008161079a565b6040805160008082526020820190925261031c918391906107a2565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036103675760405162461bcd60e51b815260040161027f90610d14565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166103b0600080516020610ea1833981519152546001600160a01b031690565b6001600160a01b0316146103d65760405162461bcd60e51b815260040161027f90610d60565b6103df8261079a565b6103eb828260016107a2565b5050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461048f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161027f565b50600080516020610ea183398151915290565b6104aa610739565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b604482015260640161027f565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610522573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105469190610dac565b905090565b600054610100900460ff161580801561056b5750600054600160ff909116105b806105855750303b158015610585575060005460ff166001145b6105e85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027f565b6000805460ff19166001179055801561060b576000805461ff0019166101001790555b61061482610912565b61061c610942565b80156103eb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61066d610739565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b604482015260640161027f565b6106a2610739565b6001600160a01b0381166106de5760405162461bcd60e51b815260206004820152600360248201526204c32360ec1b604482015260640161027f565b6001600160a01b0316600090815260fc60205260409020805460ff19166001179055565b60006001600160a01b03821661071a57506000919050565b506001600160a01b0316600090815260fc602052604090205460ff1690565b336107426104d8565b6001600160a01b0316146107985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027f565b565b61031c610739565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156107da576107d583610969565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610834575060408051601f3d908101601f1916820190925261083191810190610dc9565b60015b6108975760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161027f565b600080516020610ea183398151915281146109065760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161027f565b506107d5838383610a05565b600054610100900460ff166109395760405162461bcd60e51b815260040161027f90610de2565b61031c81610a30565b600054610100900460ff166107985760405162461bcd60e51b815260040161027f90610de2565b6001600160a01b0381163b6109d65760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161027f565b600080516020610ea183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0e83610a79565b600082511180610a1b5750805b156107d557610a2a8383610ab9565b50505050565b600054610100900460ff16610a575760405162461bcd60e51b815260040161027f90610de2565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b610a8281610969565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610ade8383604051806060016040528060278152602001610ec160279139610ae5565b9392505050565b6060600080856001600160a01b031685604051610b029190610e51565b600060405180830381855af49150503d8060008114610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b5091509150610b5386838387610b5d565b9695505050505050565b60608315610bcc578251600003610bc5576001600160a01b0385163b610bc55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027f565b5081610bd6565b610bd68383610bde565b949350505050565b815115610bee5781518083602001fd5b8060405162461bcd60e51b815260040161027f9190610e6d565b6001600160a01b038116811461031c57600080fd5b600060208284031215610c2f57600080fd5b8135610ade81610c08565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610c6357600080fd5b8235610c6e81610c08565b9150602083013567ffffffffffffffff80821115610c8b57600080fd5b818501915085601f830112610c9f57600080fd5b813581811115610cb157610cb1610c3a565b604051601f8201601f19908116603f01168101908382118183101715610cd957610cd9610c3a565b81604052828152886020848701011115610cf257600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610dbe57600080fd5b8151610ade81610c08565b600060208284031215610ddb57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610e48578181015183820152602001610e30565b50506000910152565b60008251610e63818460208701610e2d565b9190910192915050565b6020815260008251806020840152610e8c816040850160208701610e2d565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200946c3a188f7349e5012909080ca9a51d94241e76fb4945e6612fe044b50ee0364736f6c63430008120033", - "deployedBytecode": "0x60806040526004361061009c5760003560e01c80638da5cb5b116100645780638da5cb5b14610133578063c4d66de814610160578063f2fde38b14610180578063f762e734146101a0578063f9f92be4146101be578063fe575a87146101de57600080fd5b80631a895266146100a15780633659cfe6146100c35780634f1ef286146100e357806352d1902d146100f6578063715018a61461011e575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610c1d565b61020e565b005b3480156100cf57600080fd5b506100c16100de366004610c1d565b610237565b6100c16100f1366004610c50565b61031f565b34801561010257600080fd5b5061010b6103ef565b6040519081526020015b60405180910390f35b34801561012a57600080fd5b506100c16104a2565b34801561013f57600080fd5b506101486104d8565b6040516001600160a01b039091168152602001610115565b34801561016c57600080fd5b506100c161017b366004610c1d565b61054b565b34801561018c57600080fd5b506100c161019b366004610c1d565b610665565b3480156101ac57600080fd5b5060c9546001600160a01b0316610148565b3480156101ca57600080fd5b506100c16101d9366004610c1d565b61069a565b3480156101ea57600080fd5b506101fe6101f9366004610c1d565b610702565b6040519015158152602001610115565b610216610739565b6001600160a01b0316600090815260fc60205260409020805460ff19169055565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102885760405162461bcd60e51b815260040161027f90610d14565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166102d1600080516020610ea1833981519152546001600160a01b031690565b6001600160a01b0316146102f75760405162461bcd60e51b815260040161027f90610d60565b6103008161079a565b6040805160008082526020820190925261031c918391906107a2565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036103675760405162461bcd60e51b815260040161027f90610d14565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166103b0600080516020610ea1833981519152546001600160a01b031690565b6001600160a01b0316146103d65760405162461bcd60e51b815260040161027f90610d60565b6103df8261079a565b6103eb828260016107a2565b5050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461048f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161027f565b50600080516020610ea183398151915290565b6104aa610739565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b604482015260640161027f565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610522573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105469190610dac565b905090565b600054610100900460ff161580801561056b5750600054600160ff909116105b806105855750303b158015610585575060005460ff166001145b6105e85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161027f565b6000805460ff19166001179055801561060b576000805461ff0019166101001790555b61061482610912565b61061c610942565b80156103eb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61066d610739565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b604482015260640161027f565b6106a2610739565b6001600160a01b0381166106de5760405162461bcd60e51b815260206004820152600360248201526204c32360ec1b604482015260640161027f565b6001600160a01b0316600090815260fc60205260409020805460ff19166001179055565b60006001600160a01b03821661071a57506000919050565b506001600160a01b0316600090815260fc602052604090205460ff1690565b336107426104d8565b6001600160a01b0316146107985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161027f565b565b61031c610739565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156107da576107d583610969565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610834575060408051601f3d908101601f1916820190925261083191810190610dc9565b60015b6108975760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161027f565b600080516020610ea183398151915281146109065760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161027f565b506107d5838383610a05565b600054610100900460ff166109395760405162461bcd60e51b815260040161027f90610de2565b61031c81610a30565b600054610100900460ff166107985760405162461bcd60e51b815260040161027f90610de2565b6001600160a01b0381163b6109d65760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161027f565b600080516020610ea183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0e83610a79565b600082511180610a1b5750805b156107d557610a2a8383610ab9565b50505050565b600054610100900460ff16610a575760405162461bcd60e51b815260040161027f90610de2565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b610a8281610969565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610ade8383604051806060016040528060278152602001610ec160279139610ae5565b9392505050565b6060600080856001600160a01b031685604051610b029190610e51565b600060405180830381855af49150503d8060008114610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b5091509150610b5386838387610b5d565b9695505050505050565b60608315610bcc578251600003610bc5576001600160a01b0385163b610bc55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161027f565b5081610bd6565b610bd68383610bde565b949350505050565b815115610bee5781518083602001fd5b8060405162461bcd60e51b815260040161027f9190610e6d565b6001600160a01b038116811461031c57600080fd5b600060208284031215610c2f57600080fd5b8135610ade81610c08565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610c6357600080fd5b8235610c6e81610c08565b9150602083013567ffffffffffffffff80821115610c8b57600080fd5b818501915085601f830112610c9f57600080fd5b813581811115610cb157610cb1610c3a565b604051601f8201601f19908116603f01168101908382118183101715610cd957610cd9610c3a565b81604052828152886020848701011115610cf257600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610dbe57600080fd5b8151610ade81610c08565b600060208284031215610ddb57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610e48578181015183820152602001610e30565b50506000910152565b60008251610e63818460208701610e2d565b9190910192915050565b6020815260008251806020840152610e8c816040850160208701610e2d565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200946c3a188f7349e5012909080ca9a51d94241e76fb4945e6612fe044b50ee0364736f6c63430008120033", + "solcInputHash": "a268142553104e6d2a73dbd3773cf551", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Blacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unblacklisted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"blacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isBlacklisted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers and getter functions to easily check against this global blacklist.For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Blacklisted(address)\":{\"details\":\"Emitted when `account` is blacklisted.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Unblacklisted(address)\":{\"details\":\"Emitted when `account` is unblacklisted.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"blacklist(address)\":{\"params\":{\"account\":\"The account's address to be blacklisted.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalOwner_\":\"The address of the GlobalOwner contract.\"}},\"isBlacklisted(address)\":{\"params\":{\"account\":\"Address of the account to check.\"},\"returns\":{\"_0\":\"'true' if the account is blacklisted, 'false' otherwise\"}},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"unBlacklist(address)\":{\"params\":{\"account\":\"The account's address to be un-blacklisted.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"stateVariables\":{\"_list\":{\"details\":\"This mapping is made private and isBlacklisted() should be used instead.This helps saving gas in some scenario. See isBlacklisted() documentation for more details.\"}},\"title\":\"GlobalBlacklist\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"blacklist(address)\":{\"notice\":\"Adds a given account to the blacklist.\"},\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"isBlacklisted(address)\":{\"notice\":\"Checks whether a given account is blacklisted.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"unBlacklist(address)\":{\"notice\":\"Removes a given account from the blacklist.\"}},\"notice\":\"Holds a global mapping of blacklisted accounts shared by all contracts of the Ledgity Yield codebase.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalBlacklist.sol\":\"GlobalBlacklist\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalBlacklist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalBlacklist\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds a global mapping of blacklisted accounts shared by all contracts of the\\n * Ledgity Yield codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\\n * and getter functions to easily check against this global blacklist.\\n *\\n * @dev For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Mapping of accounts to their blacklist status.\\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\\n */\\n mapping(address => bool) private _list;\\n\\n /// @dev Emitted when `account` is blacklisted.\\n event Blacklisted(address account);\\n\\n /// @dev Emitted when `account` is unblacklisted.\\n event Unblacklisted(address account);\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Adds a given account to the blacklist.\\n * @param account The account's address to be blacklisted.\\n */\\n function blacklist(address account) external onlyOwner {\\n require(account != address(0), \\\"L20\\\");\\n _list[account] = true;\\n emit Blacklisted(account);\\n }\\n\\n /**\\n * @notice Removes a given account from the blacklist.\\n * @param account The account's address to be un-blacklisted.\\n */\\n function unBlacklist(address account) external onlyOwner {\\n _list[account] = false;\\n emit Unblacklisted(account);\\n }\\n\\n /**\\n * @notice Checks whether a given account is blacklisted.\\n * @param account Address of the account to check.\\n * @return 'true' if the account is blacklisted, 'false' otherwise\\n */\\n function isBlacklisted(address account) external view returns (bool) {\\n // Gas optimization: Avoid accessing storage if account is the zero address\\n // (e.g, during a mint or a burn of tokens)\\n if (account == address(0)) return false;\\n\\n // Else, return current account's blacklist status\\n return _list[account];\\n }\\n}\\n\",\"keccak256\":\"0x7e771076a06cfec935df22cf2d307df7e1f7df5b887976ec1dea30f8b68a878d\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xa3b880c4d82e796c162c99a398b569ce4a8e6d27232014b81a6a4503718f12dc\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure:\\n * The _globalOwner state must be set at initialization time and, for evident security\\n * reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9203f7a2a19def126d8ff0fde8357053ffcf1100d65ec8faec8299b6ed2c0c5a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610f8461011860003960008181610278015281816102c101528181610360015281816103a001526104330152610f846000f3fe60806040526004361061009c5760003560e01c80638da5cb5b116100645780638da5cb5b14610133578063c4d66de814610160578063f2fde38b14610180578063f762e734146101a0578063f9f92be4146101be578063fe575a87146101de57600080fd5b80631a895266146100a15780633659cfe6146100c35780634f1ef286146100e357806352d1902d146100f6578063715018a61461011e575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610c84565b61020e565b005b3480156100cf57600080fd5b506100c16100de366004610c84565b61026e565b6100c16100f1366004610cb7565b610356565b34801561010257600080fd5b5061010b610426565b6040519081526020015b60405180910390f35b34801561012a57600080fd5b506100c16104d9565b34801561013f57600080fd5b5061014861050f565b6040516001600160a01b039091168152602001610115565b34801561016c57600080fd5b506100c161017b366004610c84565b610582565b34801561018c57600080fd5b506100c161019b366004610c84565b61069c565b3480156101ac57600080fd5b5060c9546001600160a01b0316610148565b3480156101ca57600080fd5b506100c16101d9366004610c84565b6106d1565b3480156101ea57600080fd5b506101fe6101f9366004610c84565b610769565b6040519015158152602001610115565b6102166107a0565b6001600160a01b038116600081815260fc6020908152604091829020805460ff1916905590519182527f7534c63860313c46c473e4e98328f37017e9674e2162faf1a3ad7a96236c3b7b91015b60405180910390a150565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102bf5760405162461bcd60e51b81526004016102b690610d7b565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610308600080516020610f08833981519152546001600160a01b031690565b6001600160a01b03161461032e5760405162461bcd60e51b81526004016102b690610dc7565b61033781610801565b6040805160008082526020820190925261035391839190610809565b50565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361039e5760405162461bcd60e51b81526004016102b690610d7b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166103e7600080516020610f08833981519152546001600160a01b031690565b6001600160a01b03161461040d5760405162461bcd60e51b81526004016102b690610dc7565b61041682610801565b61042282826001610809565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104c65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016102b6565b50600080516020610f0883398151915290565b6104e16107a0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016102b6565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190610e13565b905090565b600054610100900460ff16158080156105a25750600054600160ff909116105b806105bc5750303b1580156105bc575060005460ff166001145b61061f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102b6565b6000805460ff191660011790558015610642576000805461ff0019166101001790555b61064b82610979565b6106536109a9565b8015610422576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6106a46107a0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016102b6565b6106d96107a0565b6001600160a01b0381166107155760405162461bcd60e51b815260206004820152600360248201526204c32360ec1b60448201526064016102b6565b6001600160a01b038116600081815260fc6020908152604091829020805460ff1916600117905590519182527fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8559101610263565b60006001600160a01b03821661078157506000919050565b506001600160a01b0316600090815260fc602052604090205460ff1690565b336107a961050f565b6001600160a01b0316146107ff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102b6565b565b6103536107a0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156108415761083c836109d0565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561089b575060408051601f3d908101601f1916820190925261089891810190610e30565b60015b6108fe5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016102b6565b600080516020610f08833981519152811461096d5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016102b6565b5061083c838383610a6c565b600054610100900460ff166109a05760405162461bcd60e51b81526004016102b690610e49565b61035381610a97565b600054610100900460ff166107ff5760405162461bcd60e51b81526004016102b690610e49565b6001600160a01b0381163b610a3d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016102b6565b600080516020610f0883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a7583610ae0565b600082511180610a825750805b1561083c57610a918383610b20565b50505050565b600054610100900460ff16610abe5760405162461bcd60e51b81526004016102b690610e49565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b610ae9816109d0565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b458383604051806060016040528060278152602001610f2860279139610b4c565b9392505050565b6060600080856001600160a01b031685604051610b699190610eb8565b600060405180830381855af49150503d8060008114610ba4576040519150601f19603f3d011682016040523d82523d6000602084013e610ba9565b606091505b5091509150610bba86838387610bc4565b9695505050505050565b60608315610c33578251600003610c2c576001600160a01b0385163b610c2c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102b6565b5081610c3d565b610c3d8383610c45565b949350505050565b815115610c555781518083602001fd5b8060405162461bcd60e51b81526004016102b69190610ed4565b6001600160a01b038116811461035357600080fd5b600060208284031215610c9657600080fd5b8135610b4581610c6f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610cca57600080fd5b8235610cd581610c6f565b9150602083013567ffffffffffffffff80821115610cf257600080fd5b818501915085601f830112610d0657600080fd5b813581811115610d1857610d18610ca1565b604051601f8201601f19908116603f01168101908382118183101715610d4057610d40610ca1565b81604052828152886020848701011115610d5957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e2557600080fd5b8151610b4581610c6f565b600060208284031215610e4257600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610eaf578181015183820152602001610e97565b50506000910152565b60008251610eca818460208701610e94565b9190910192915050565b6020815260008251806020840152610ef3816040850160208701610e94565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a018129cb5f06c0c7c5a811655ab761d448869bf794f6ffc6aaf1e624507d4f564736f6c63430008120033", + "deployedBytecode": "0x60806040526004361061009c5760003560e01c80638da5cb5b116100645780638da5cb5b14610133578063c4d66de814610160578063f2fde38b14610180578063f762e734146101a0578063f9f92be4146101be578063fe575a87146101de57600080fd5b80631a895266146100a15780633659cfe6146100c35780634f1ef286146100e357806352d1902d146100f6578063715018a61461011e575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610c84565b61020e565b005b3480156100cf57600080fd5b506100c16100de366004610c84565b61026e565b6100c16100f1366004610cb7565b610356565b34801561010257600080fd5b5061010b610426565b6040519081526020015b60405180910390f35b34801561012a57600080fd5b506100c16104d9565b34801561013f57600080fd5b5061014861050f565b6040516001600160a01b039091168152602001610115565b34801561016c57600080fd5b506100c161017b366004610c84565b610582565b34801561018c57600080fd5b506100c161019b366004610c84565b61069c565b3480156101ac57600080fd5b5060c9546001600160a01b0316610148565b3480156101ca57600080fd5b506100c16101d9366004610c84565b6106d1565b3480156101ea57600080fd5b506101fe6101f9366004610c84565b610769565b6040519015158152602001610115565b6102166107a0565b6001600160a01b038116600081815260fc6020908152604091829020805460ff1916905590519182527f7534c63860313c46c473e4e98328f37017e9674e2162faf1a3ad7a96236c3b7b91015b60405180910390a150565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102bf5760405162461bcd60e51b81526004016102b690610d7b565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610308600080516020610f08833981519152546001600160a01b031690565b6001600160a01b03161461032e5760405162461bcd60e51b81526004016102b690610dc7565b61033781610801565b6040805160008082526020820190925261035391839190610809565b50565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361039e5760405162461bcd60e51b81526004016102b690610d7b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166103e7600080516020610f08833981519152546001600160a01b031690565b6001600160a01b03161461040d5760405162461bcd60e51b81526004016102b690610dc7565b61041682610801565b61042282826001610809565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104c65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016102b6565b50600080516020610f0883398151915290565b6104e16107a0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016102b6565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190610e13565b905090565b600054610100900460ff16158080156105a25750600054600160ff909116105b806105bc5750303b1580156105bc575060005460ff166001145b61061f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016102b6565b6000805460ff191660011790558015610642576000805461ff0019166101001790555b61064b82610979565b6106536109a9565b8015610422576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6106a46107a0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016102b6565b6106d96107a0565b6001600160a01b0381166107155760405162461bcd60e51b815260206004820152600360248201526204c32360ec1b60448201526064016102b6565b6001600160a01b038116600081815260fc6020908152604091829020805460ff1916600117905590519182527fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b8559101610263565b60006001600160a01b03821661078157506000919050565b506001600160a01b0316600090815260fc602052604090205460ff1690565b336107a961050f565b6001600160a01b0316146107ff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102b6565b565b6103536107a0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156108415761083c836109d0565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561089b575060408051601f3d908101601f1916820190925261089891810190610e30565b60015b6108fe5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016102b6565b600080516020610f08833981519152811461096d5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016102b6565b5061083c838383610a6c565b600054610100900460ff166109a05760405162461bcd60e51b81526004016102b690610e49565b61035381610a97565b600054610100900460ff166107ff5760405162461bcd60e51b81526004016102b690610e49565b6001600160a01b0381163b610a3d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016102b6565b600080516020610f0883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a7583610ae0565b600082511180610a825750805b1561083c57610a918383610b20565b50505050565b600054610100900460ff16610abe5760405162461bcd60e51b81526004016102b690610e49565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b610ae9816109d0565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b458383604051806060016040528060278152602001610f2860279139610b4c565b9392505050565b6060600080856001600160a01b031685604051610b699190610eb8565b600060405180830381855af49150503d8060008114610ba4576040519150601f19603f3d011682016040523d82523d6000602084013e610ba9565b606091505b5091509150610bba86838387610bc4565b9695505050505050565b60608315610c33578251600003610c2c576001600160a01b0385163b610c2c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102b6565b5081610c3d565b610c3d8383610c45565b949350505050565b815115610c555781518083602001fd5b8060405162461bcd60e51b81526004016102b69190610ed4565b6001600160a01b038116811461035357600080fd5b600060208284031215610c9657600080fd5b8135610b4581610c6f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610cca57600080fd5b8235610cd581610c6f565b9150602083013567ffffffffffffffff80821115610cf257600080fd5b818501915085601f830112610d0657600080fd5b813581811115610d1857610d18610ca1565b604051601f8201601f19908116603f01168101908382118183101715610d4057610d40610ca1565b81604052828152886020848701011115610d5957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e2557600080fd5b8151610b4581610c6f565b600060208284031215610e4257600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610eaf578181015183820152602001610e97565b50506000910152565b60008251610eca818460208701610e94565b9190910192915050565b6020815260008251806020840152610ef3816040850160208701610e94565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a018129cb5f06c0c7c5a811655ab761d448869bf794f6ffc6aaf1e624507d4f564736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", @@ -278,9 +304,15 @@ "BeaconUpgraded(address)": { "details": "Emitted when the beacon is changed." }, + "Blacklisted(address)": { + "details": "Emitted when `account` is blacklisted." + }, "Initialized(uint8)": { "details": "Triggered when the contract has been initialized or reinitialized." }, + "Unblacklisted(address)": { + "details": "Emitted when `account` is unblacklisted." + }, "Upgraded(address)": { "details": "Emitted when the implementation is upgraded." } @@ -376,7 +408,7 @@ "notice": "Removes a given account from the blacklist." } }, - "notice": "Maintains a global mapping of blacklisted accounts on-chain. All contracts within the Ledgity Yield codebase reference this mapping to prevent access by blacklisted accounts.", + "notice": "Holds a global mapping of blacklisted accounts shared by all contracts of the Ledgity Yield codebase.", "version": 1 }, "storageLayout": { @@ -438,15 +470,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7671, + "astId": 6980, "contract": "contracts/src/GlobalBlacklist.sol:GlobalBlacklist", "label": "_globalOwner", "offset": 0, "slot": "201", - "type": "t_contract(GlobalOwner)4909" + "type": "t_contract(GlobalOwner)4271" }, { - "astId": 7755, + "astId": 7064, "contract": "contracts/src/GlobalBlacklist.sol:GlobalBlacklist", "label": "__gap", "offset": 0, @@ -454,7 +486,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 4765, + "astId": 4109, "contract": "contracts/src/GlobalBlacklist.sol:GlobalBlacklist", "label": "_list", "offset": 0, @@ -485,7 +517,7 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(GlobalOwner)4909": { + "t_contract(GlobalOwner)4271": { "encoding": "inplace", "label": "contract GlobalOwner", "numberOfBytes": "20" diff --git a/contracts/hardhat/deployments/localhost/GlobalBlacklist_Proxy.json b/contracts/hardhat/deployments/localhost/GlobalBlacklist_Proxy.json index 12559d4c..2e6042d9 100644 --- a/contracts/hardhat/deployments/localhost/GlobalBlacklist_Proxy.json +++ b/contracts/hardhat/deployments/localhost/GlobalBlacklist_Proxy.json @@ -79,7 +79,7 @@ "transactionIndex": 0, "gasUsed": "332581", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000002000000000240000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000080400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae", + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362", "transactionHash": "0xaee795c43b7a10f17952d609bd43b93152e955c2fa1993abf9cfc84351844bd5", "logs": [ { @@ -93,7 +93,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae" + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362" }, { "transactionIndex": 0, @@ -105,7 +105,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0x886dcf5ffec08246969c6a56766b9fae36e3f383a12341b1584700a7efd36eae" + "blockHash": "0xe41aef68019bd08276871a0e87bafdb090c9d6ea2ca11a8d6a6f6dddfa3b5362" } ], "blockNumber": 6, diff --git a/contracts/hardhat/deployments/localhost/GlobalOwner.json b/contracts/hardhat/deployments/localhost/GlobalOwner.json index 3af5024b..7c2fda22 100644 --- a/contracts/hardhat/deployments/localhost/GlobalOwner.json +++ b/contracts/hardhat/deployments/localhost/GlobalOwner.json @@ -234,7 +234,7 @@ "transactionIndex": 0, "gasUsed": "335746", "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000100800800000004000000000000000000000000400000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000200000000000041000000000002008000000000000000020000000000000000000000000000000000000000000000000800000000000000000", - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b", + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7", "transactionHash": "0x067b5a384834e714e5876cb84045bb71a643ba0e765a789a33d142522ef51d3a", "logs": [ { @@ -248,7 +248,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" }, { "transactionIndex": 0, @@ -262,7 +262,7 @@ ], "data": "0x", "logIndex": 1, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" }, { "transactionIndex": 0, @@ -274,7 +274,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 2, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" } ], "blockNumber": 2, diff --git a/contracts/hardhat/deployments/localhost/GlobalOwner_Implementation.json b/contracts/hardhat/deployments/localhost/GlobalOwner_Implementation.json index 48e404d2..cc8b60b8 100644 --- a/contracts/hardhat/deployments/localhost/GlobalOwner_Implementation.json +++ b/contracts/hardhat/deployments/localhost/GlobalOwner_Implementation.json @@ -207,7 +207,7 @@ "type": "function" } ], - "transactionHash": "0x9da9750d1fc2cc09a6bc301d1bd57a048df1f2e6c2ddca447a77db27a4ea7a9b", + "transactionHash": "0xb63f6bf580c1b82c1def1aae23537a6132b0c9bcc27152a33b003c4dec4dfabe", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", @@ -215,20 +215,20 @@ "transactionIndex": 0, "gasUsed": "862049", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000200000000000000000000000000000000000400000000000000000000000000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa5660eb0c1d26fe2004ef7a03c2a66821d3e191d20dd9ee1ef0e2f0f766ac8bb", - "transactionHash": "0x9da9750d1fc2cc09a6bc301d1bd57a048df1f2e6c2ddca447a77db27a4ea7a9b", + "blockHash": "0xa2306a1dd17a4abdf99cd56dc5e2e57ecf5b36ea096bd8abcf5572a358ed2f80", + "transactionHash": "0xb63f6bf580c1b82c1def1aae23537a6132b0c9bcc27152a33b003c4dec4dfabe", "logs": [ { "transactionIndex": 0, "blockNumber": 1, - "transactionHash": "0x9da9750d1fc2cc09a6bc301d1bd57a048df1f2e6c2ddca447a77db27a4ea7a9b", + "transactionHash": "0xb63f6bf580c1b82c1def1aae23537a6132b0c9bcc27152a33b003c4dec4dfabe", "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0xa5660eb0c1d26fe2004ef7a03c2a66821d3e191d20dd9ee1ef0e2f0f766ac8bb" + "blockHash": "0xa2306a1dd17a4abdf99cd56dc5e2e57ecf5b36ea096bd8abcf5572a358ed2f80" } ], "blockNumber": 1, @@ -238,10 +238,10 @@ }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalOwnableUpgradeable abstract contract. This provides them with an overriden owner() function that retrieves the owner's address from this contract instead.For further details, see \\\"GlobalOwner\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"initialize()\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"GlobalOwner\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"initialize()\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"}},\"notice\":\"Maintains the address of a global owner account shared by all contracts of the Ledgity Yield's codebase.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalOwner.sol\":\"GlobalOwner\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610e2a610118600039600081816101a1015281816101ea01528181610289015281816102c9015261035c0152610e2a6000f3fe6080604052600436106100865760003560e01c806379ba50971161005957806379ba5097146100fd5780638129fc1c146101125780638da5cb5b14610127578063e30c397814610159578063f2fde38b1461017757600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b4b565b610197565b005b6100ab6100bb366004610b7c565b61027f565b3480156100cc57600080fd5b506100d561034f565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610402565b34801561010957600080fd5b506100ab610416565b34801561011e57600080fd5b506100ab61048d565b34801561013357600080fd5b506097546001600160a01b03165b6040516001600160a01b0390911681526020016100df565b34801561016557600080fd5b5060c9546001600160a01b0316610141565b34801561018357600080fd5b506100ab610192366004610b4b565b6105a5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101e85760405162461bcd60e51b81526004016101df90610c3e565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610231600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146102575760405162461bcd60e51b81526004016101df90610c8a565b61026081610616565b6040805160008082526020820190925261027c9183919061061e565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102c75760405162461bcd60e51b81526004016101df90610c3e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610310600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146103365760405162461bcd60e51b81526004016101df90610c8a565b61033f82610616565b61034b8282600161061e565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103ef5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101df565b50600080516020610dae83398151915290565b61040a61078e565b61041460006107e8565b565b60c95433906001600160a01b031681146104845760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016101df565b61027c816107e8565b600054610100900460ff16158080156104ad5750600054600160ff909116105b806104c75750303b1580156104c7575060005460ff166001145b61052a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101df565b6000805460ff19166001179055801561054d576000805461ff0019166101001790555b610555610801565b61055d610830565b801561027c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6105ad61078e565b60c980546001600160a01b0383166001600160a01b031990911681179091556105de6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61027c61078e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106565761065183610857565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106b0575060408051601f3d908101601f191682019092526106ad91810190610cd6565b60015b6107135760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101df565b600080516020610dae83398151915281146107825760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101df565b506106518383836108f3565b6097546001600160a01b031633146104145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101df565b60c980546001600160a01b031916905561027c8161091e565b600054610100900460ff166108285760405162461bcd60e51b81526004016101df90610cef565b610414610970565b600054610100900460ff166104145760405162461bcd60e51b81526004016101df90610cef565b6001600160a01b0381163b6108c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101df565b600080516020610dae83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6108fc836109a0565b6000825111806109095750805b156106515761091883836109e0565b50505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166109975760405162461bcd60e51b81526004016101df90610cef565b610414336107e8565b6109a981610857565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610a058383604051806060016040528060278152602001610dce60279139610a0c565b9392505050565b6060600080856001600160a01b031685604051610a299190610d5e565b600060405180830381855af49150503d8060008114610a64576040519150601f19603f3d011682016040523d82523d6000602084013e610a69565b606091505b5091509150610a7a86838387610a84565b9695505050505050565b60608315610af3578251600003610aec576001600160a01b0385163b610aec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101df565b5081610afd565b610afd8383610b05565b949350505050565b815115610b155781518083602001fd5b8060405162461bcd60e51b81526004016101df9190610d7a565b80356001600160a01b0381168114610b4657600080fd5b919050565b600060208284031215610b5d57600080fd5b610a0582610b2f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b8f57600080fd5b610b9883610b2f565b9150602083013567ffffffffffffffff80821115610bb557600080fd5b818501915085601f830112610bc957600080fd5b813581811115610bdb57610bdb610b66565b604051601f8201601f19908116603f01168101908382118183101715610c0357610c03610b66565b81604052828152886020848701011115610c1c57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ce857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d55578181015183820152602001610d3d565b50506000910152565b60008251610d70818460208701610d3a565b9190910192915050565b6020815260008251806020840152610d99816040850160208701610d3a565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c010223d862abaaa519a2d405f58a04f6e43ecbd21bec98f833b4f584b6ab7e464736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106100865760003560e01c806379ba50971161005957806379ba5097146100fd5780638129fc1c146101125780638da5cb5b14610127578063e30c397814610159578063f2fde38b1461017757600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b4b565b610197565b005b6100ab6100bb366004610b7c565b61027f565b3480156100cc57600080fd5b506100d561034f565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610402565b34801561010957600080fd5b506100ab610416565b34801561011e57600080fd5b506100ab61048d565b34801561013357600080fd5b506097546001600160a01b03165b6040516001600160a01b0390911681526020016100df565b34801561016557600080fd5b5060c9546001600160a01b0316610141565b34801561018357600080fd5b506100ab610192366004610b4b565b6105a5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101e85760405162461bcd60e51b81526004016101df90610c3e565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610231600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146102575760405162461bcd60e51b81526004016101df90610c8a565b61026081610616565b6040805160008082526020820190925261027c9183919061061e565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102c75760405162461bcd60e51b81526004016101df90610c3e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610310600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146103365760405162461bcd60e51b81526004016101df90610c8a565b61033f82610616565b61034b8282600161061e565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103ef5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101df565b50600080516020610dae83398151915290565b61040a61078e565b61041460006107e8565b565b60c95433906001600160a01b031681146104845760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016101df565b61027c816107e8565b600054610100900460ff16158080156104ad5750600054600160ff909116105b806104c75750303b1580156104c7575060005460ff166001145b61052a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101df565b6000805460ff19166001179055801561054d576000805461ff0019166101001790555b610555610801565b61055d610830565b801561027c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6105ad61078e565b60c980546001600160a01b0383166001600160a01b031990911681179091556105de6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61027c61078e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106565761065183610857565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106b0575060408051601f3d908101601f191682019092526106ad91810190610cd6565b60015b6107135760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101df565b600080516020610dae83398151915281146107825760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101df565b506106518383836108f3565b6097546001600160a01b031633146104145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101df565b60c980546001600160a01b031916905561027c8161091e565b600054610100900460ff166108285760405162461bcd60e51b81526004016101df90610cef565b610414610970565b600054610100900460ff166104145760405162461bcd60e51b81526004016101df90610cef565b6001600160a01b0381163b6108c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101df565b600080516020610dae83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6108fc836109a0565b6000825111806109095750805b156106515761091883836109e0565b50505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166109975760405162461bcd60e51b81526004016101df90610cef565b610414336107e8565b6109a981610857565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610a058383604051806060016040528060278152602001610dce60279139610a0c565b9392505050565b6060600080856001600160a01b031685604051610a299190610d5e565b600060405180830381855af49150503d8060008114610a64576040519150601f19603f3d011682016040523d82523d6000602084013e610a69565b606091505b5091509150610a7a86838387610a84565b9695505050505050565b60608315610af3578251600003610aec576001600160a01b0385163b610aec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101df565b5081610afd565b610afd8383610b05565b949350505050565b815115610b155781518083602001fd5b8060405162461bcd60e51b81526004016101df9190610d7a565b80356001600160a01b0381168114610b4657600080fd5b919050565b600060208284031215610b5d57600080fd5b610a0582610b2f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b8f57600080fd5b610b9883610b2f565b9150602083013567ffffffffffffffff80821115610bb557600080fd5b818501915085601f830112610bc957600080fd5b813581811115610bdb57610bdb610b66565b604051601f8201601f19908116603f01168101908382118183101715610c0357610c03610b66565b81604052828152886020848701011115610c1c57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ce857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d55578181015183820152602001610d3d565b50506000910152565b60008251610d70818460208701610d3a565b9190910192915050565b6020815260008251806020840152610d99816040850160208701610d3a565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c010223d862abaaa519a2d405f58a04f6e43ecbd21bec98f833b4f584b6ab7e464736f6c63430008120033", + "solcInputHash": "3d20376140786af30d287ee442e9b474", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalOwnableUpgradeable abstract contract. This provides them with an overriden owner() function that retrieves the owner's address from this contract instead.For further details, see \\\"GlobalOwner\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"initialize()\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"GlobalOwner\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"initialize()\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"}},\"notice\":\"Holds the address of a global owner account shared by all contracts of the Ledgity Yield's codebase.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalOwner.sol\":\"GlobalOwner\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xa3b880c4d82e796c162c99a398b569ce4a8e6d27232014b81a6a4503718f12dc\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610e2a610118600039600081816101a1015281816101ea01528181610289015281816102c9015261035c0152610e2a6000f3fe6080604052600436106100865760003560e01c806379ba50971161005957806379ba5097146100fd5780638129fc1c146101125780638da5cb5b14610127578063e30c397814610159578063f2fde38b1461017757600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b4b565b610197565b005b6100ab6100bb366004610b7c565b61027f565b3480156100cc57600080fd5b506100d561034f565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610402565b34801561010957600080fd5b506100ab610416565b34801561011e57600080fd5b506100ab61048d565b34801561013357600080fd5b506097546001600160a01b03165b6040516001600160a01b0390911681526020016100df565b34801561016557600080fd5b5060c9546001600160a01b0316610141565b34801561018357600080fd5b506100ab610192366004610b4b565b6105a5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101e85760405162461bcd60e51b81526004016101df90610c3e565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610231600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146102575760405162461bcd60e51b81526004016101df90610c8a565b61026081610616565b6040805160008082526020820190925261027c9183919061061e565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102c75760405162461bcd60e51b81526004016101df90610c3e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610310600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146103365760405162461bcd60e51b81526004016101df90610c8a565b61033f82610616565b61034b8282600161061e565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103ef5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101df565b50600080516020610dae83398151915290565b61040a61078e565b61041460006107e8565b565b60c95433906001600160a01b031681146104845760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016101df565b61027c816107e8565b600054610100900460ff16158080156104ad5750600054600160ff909116105b806104c75750303b1580156104c7575060005460ff166001145b61052a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101df565b6000805460ff19166001179055801561054d576000805461ff0019166101001790555b610555610801565b61055d610830565b801561027c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6105ad61078e565b60c980546001600160a01b0383166001600160a01b031990911681179091556105de6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61027c61078e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106565761065183610857565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106b0575060408051601f3d908101601f191682019092526106ad91810190610cd6565b60015b6107135760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101df565b600080516020610dae83398151915281146107825760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101df565b506106518383836108f3565b6097546001600160a01b031633146104145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101df565b60c980546001600160a01b031916905561027c8161091e565b600054610100900460ff166108285760405162461bcd60e51b81526004016101df90610cef565b610414610970565b600054610100900460ff166104145760405162461bcd60e51b81526004016101df90610cef565b6001600160a01b0381163b6108c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101df565b600080516020610dae83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6108fc836109a0565b6000825111806109095750805b156106515761091883836109e0565b50505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166109975760405162461bcd60e51b81526004016101df90610cef565b610414336107e8565b6109a981610857565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610a058383604051806060016040528060278152602001610dce60279139610a0c565b9392505050565b6060600080856001600160a01b031685604051610a299190610d5e565b600060405180830381855af49150503d8060008114610a64576040519150601f19603f3d011682016040523d82523d6000602084013e610a69565b606091505b5091509150610a7a86838387610a84565b9695505050505050565b60608315610af3578251600003610aec576001600160a01b0385163b610aec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101df565b5081610afd565b610afd8383610b05565b949350505050565b815115610b155781518083602001fd5b8060405162461bcd60e51b81526004016101df9190610d7a565b80356001600160a01b0381168114610b4657600080fd5b919050565b600060208284031215610b5d57600080fd5b610a0582610b2f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b8f57600080fd5b610b9883610b2f565b9150602083013567ffffffffffffffff80821115610bb557600080fd5b818501915085601f830112610bc957600080fd5b813581811115610bdb57610bdb610b66565b604051601f8201601f19908116603f01168101908382118183101715610c0357610c03610b66565b81604052828152886020848701011115610c1c57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ce857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d55578181015183820152602001610d3d565b50506000910152565b60008251610d70818460208701610d3a565b9190910192915050565b6020815260008251806020840152610d99816040850160208701610d3a565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bf4d86ddafb4e67006b30af9e139567cad9fe8a30e6aad3fb9c85abe69dc796264736f6c63430008120033", + "deployedBytecode": "0x6080604052600436106100865760003560e01c806379ba50971161005957806379ba5097146100fd5780638129fc1c146101125780638da5cb5b14610127578063e30c397814610159578063f2fde38b1461017757600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b4b565b610197565b005b6100ab6100bb366004610b7c565b61027f565b3480156100cc57600080fd5b506100d561034f565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610402565b34801561010957600080fd5b506100ab610416565b34801561011e57600080fd5b506100ab61048d565b34801561013357600080fd5b506097546001600160a01b03165b6040516001600160a01b0390911681526020016100df565b34801561016557600080fd5b5060c9546001600160a01b0316610141565b34801561018357600080fd5b506100ab610192366004610b4b565b6105a5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101e85760405162461bcd60e51b81526004016101df90610c3e565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610231600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146102575760405162461bcd60e51b81526004016101df90610c8a565b61026081610616565b6040805160008082526020820190925261027c9183919061061e565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102c75760405162461bcd60e51b81526004016101df90610c3e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610310600080516020610dae833981519152546001600160a01b031690565b6001600160a01b0316146103365760405162461bcd60e51b81526004016101df90610c8a565b61033f82610616565b61034b8282600161061e565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103ef5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101df565b50600080516020610dae83398151915290565b61040a61078e565b61041460006107e8565b565b60c95433906001600160a01b031681146104845760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016101df565b61027c816107e8565b600054610100900460ff16158080156104ad5750600054600160ff909116105b806104c75750303b1580156104c7575060005460ff166001145b61052a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101df565b6000805460ff19166001179055801561054d576000805461ff0019166101001790555b610555610801565b61055d610830565b801561027c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b6105ad61078e565b60c980546001600160a01b0383166001600160a01b031990911681179091556105de6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61027c61078e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106565761065183610857565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106b0575060408051601f3d908101601f191682019092526106ad91810190610cd6565b60015b6107135760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101df565b600080516020610dae83398151915281146107825760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101df565b506106518383836108f3565b6097546001600160a01b031633146104145760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101df565b60c980546001600160a01b031916905561027c8161091e565b600054610100900460ff166108285760405162461bcd60e51b81526004016101df90610cef565b610414610970565b600054610100900460ff166104145760405162461bcd60e51b81526004016101df90610cef565b6001600160a01b0381163b6108c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101df565b600080516020610dae83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6108fc836109a0565b6000825111806109095750805b156106515761091883836109e0565b50505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166109975760405162461bcd60e51b81526004016101df90610cef565b610414336107e8565b6109a981610857565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610a058383604051806060016040528060278152602001610dce60279139610a0c565b9392505050565b6060600080856001600160a01b031685604051610a299190610d5e565b600060405180830381855af49150503d8060008114610a64576040519150601f19603f3d011682016040523d82523d6000602084013e610a69565b606091505b5091509150610a7a86838387610a84565b9695505050505050565b60608315610af3578251600003610aec576001600160a01b0385163b610aec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101df565b5081610afd565b610afd8383610b05565b949350505050565b815115610b155781518083602001fd5b8060405162461bcd60e51b81526004016101df9190610d7a565b80356001600160a01b0381168114610b4657600080fd5b919050565b600060208284031215610b5d57600080fd5b610a0582610b2f565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b8f57600080fd5b610b9883610b2f565b9150602083013567ffffffffffffffff80821115610bb557600080fd5b818501915085601f830112610bc957600080fd5b813581811115610bdb57610bdb610b66565b604051601f8201601f19908116603f01168101908382118183101715610c0357610c03610b66565b81604052828152886020848701011115610c1c57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ce857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d55578181015183820152602001610d3d565b50506000910152565b60008251610d70818460208701610d3a565b9190910192915050565b6020815260008251806020840152610d99816040850160208701610d3a565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bf4d86ddafb4e67006b30af9e139567cad9fe8a30e6aad3fb9c85abe69dc796264736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", @@ -309,7 +309,7 @@ "notice": "Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts." } }, - "notice": "Maintains the address of a global owner account shared by all contracts of the Ledgity Yield's codebase.", + "notice": "Holds the address of a global owner account shared by all contracts of the Ledgity Yield's codebase.", "version": 1 }, "storageLayout": { diff --git a/contracts/hardhat/deployments/localhost/GlobalOwner_Proxy.json b/contracts/hardhat/deployments/localhost/GlobalOwner_Proxy.json index 0979a2c8..93fe0a2f 100644 --- a/contracts/hardhat/deployments/localhost/GlobalOwner_Proxy.json +++ b/contracts/hardhat/deployments/localhost/GlobalOwner_Proxy.json @@ -79,7 +79,7 @@ "transactionIndex": 0, "gasUsed": "335746", "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002000001000000000000000000000000000000000000020000000000000100800800000004000000000000000000000000400000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000200000000000041000000000002008000000000000000020000000000000000000000000000000000000000000000000800000000000000000", - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b", + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7", "transactionHash": "0x067b5a384834e714e5876cb84045bb71a643ba0e765a789a33d142522ef51d3a", "logs": [ { @@ -93,7 +93,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" }, { "transactionIndex": 0, @@ -107,7 +107,7 @@ ], "data": "0x", "logIndex": 1, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" }, { "transactionIndex": 0, @@ -119,7 +119,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 2, - "blockHash": "0x64f5a1eb18efe1452dd608f42cd7fb4fa0b1c604c80b27d5ab304ac3cb98119b" + "blockHash": "0xa0b5b3b6ef71de359bef7e27f9892371b14bbe3c366f7359d1d4d079b68779c7" } ], "blockNumber": 2, diff --git a/contracts/hardhat/deployments/localhost/GlobalPause.json b/contracts/hardhat/deployments/localhost/GlobalPause.json index ae1490a4..3894364f 100644 --- a/contracts/hardhat/deployments/localhost/GlobalPause.json +++ b/contracts/hardhat/deployments/localhost/GlobalPause.json @@ -267,7 +267,7 @@ "transactionIndex": 0, "gasUsed": "335171", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000400000000080000400000000000000000000000000001000000000000000000000000000002000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3", + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038", "transactionHash": "0x5553bb49f49e690220e8077b3bf6fd1f8a403d84d29402f881adf2be52fd542f", "logs": [ { @@ -281,7 +281,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3" + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038" }, { "transactionIndex": 0, @@ -293,7 +293,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3" + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038" } ], "blockNumber": 4, diff --git a/contracts/hardhat/deployments/localhost/GlobalPause_Implementation.json b/contracts/hardhat/deployments/localhost/GlobalPause_Implementation.json index 9de10e6b..1e6c54a7 100644 --- a/contracts/hardhat/deployments/localhost/GlobalPause_Implementation.json +++ b/contracts/hardhat/deployments/localhost/GlobalPause_Implementation.json @@ -240,41 +240,41 @@ "type": "function" } ], - "transactionHash": "0xa9c8e31a2daef57f823bf8fef3e3a70977249fc38f7600b11d0f485163ded3bb", + "transactionHash": "0xc17eac60177a21070864b467841b0e9581731b07eb366aa98a9fea2ae3a191d8", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "transactionIndex": 0, - "gasUsed": "955351", + "gasUsed": "955363", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000", - "blockHash": "0xad2cb1591b4ffc07d6d6e0f64449ec2e4ac4fd505ba8171f2fd7fbd8a4bc0ddd", - "transactionHash": "0xa9c8e31a2daef57f823bf8fef3e3a70977249fc38f7600b11d0f485163ded3bb", + "blockHash": "0xdf80cd13cc6b04e328deea74012ce477493ad66d62475ffc90078225233d3dea", + "transactionHash": "0xc17eac60177a21070864b467841b0e9581731b07eb366aa98a9fea2ae3a191d8", "logs": [ { "transactionIndex": 0, "blockNumber": 3, - "transactionHash": "0xa9c8e31a2daef57f823bf8fef3e3a70977249fc38f7600b11d0f485163ded3bb", + "transactionHash": "0xc17eac60177a21070864b467841b0e9581731b07eb366aa98a9fea2ae3a191d8", "address": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0xad2cb1591b4ffc07d6d6e0f64449ec2e4ac4fd505ba8171f2fd7fbd8a4bc0ddd" + "blockHash": "0xdf80cd13cc6b04e328deea74012ce477493ad66d62475ffc90078225233d3dea" } ], "blockNumber": 3, - "cumulativeGasUsed": "955351", + "cumulativeGasUsed": "955363", "status": 1, "byzantium": true }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalPausableUpgradeable abstract contract. This provides them with an overriden paused() function that retrieves the pause state from this contract instead.For further details, see \\\"GlobalPause\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalOwner_\":\"The address of the GlobalOwner contract.\"}},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"pause()\":{\"details\":\"Public implementation of PausableUpgradeable's pausing and unpausing functions but restricted to contract's owner.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"GlobalPause\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"}},\"notice\":\"Maintains a global pause state shared by all contracts of the Ledgity Yield codebase.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalPause.sol\":\"GlobalPause\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"},\"contracts/src/GlobalPause.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalPause\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global pause state shared by all contracts of the Ledgity Yield\\n * codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\\n * paused() function that retrieves the pause state from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalPause\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalPause is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n PausableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\\n * but restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n}\\n\",\"keccak256\":\"0x5933aec9779d2d84e00678bf489c8349d8be84fcf479f2a18eb8571a3b900ada\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x59c14d38e9e96d4f60cf2fd626c56e23928fce85107ac8d603dfdb90c9d81ec4\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610fda610118600039600081816101f50152818161023e015281816102ef0152818161032f01526103c20152610fda6000f3fe60806040526004361061009c5760003560e01c8063715018a611610064578063715018a6146101365780638456cb591461014b5780638da5cb5b14610160578063c4d66de81461018d578063f2fde38b146101ad578063f762e734146101cd57600080fd5b80633659cfe6146100a15780633f4ba83a146100c35780634f1ef286146100d857806352d1902d146100eb5780635c975abb14610113575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610cda565b6101eb565b005b3480156100cf57600080fd5b506100c16102d3565b6100c16100e6366004610d0d565b6102e5565b3480156100f757600080fd5b506101006103b5565b6040519081526020015b60405180910390f35b34801561011f57600080fd5b5060fc5460ff16604051901515815260200161010a565b34801561014257600080fd5b506100c1610468565b34801561015757600080fd5b506100c161049e565b34801561016c57600080fd5b506101756104ae565b6040516001600160a01b03909116815260200161010a565b34801561019957600080fd5b506100c16101a8366004610cda565b610521565b3480156101b957600080fd5b506100c16101c8366004610cda565b610643565b3480156101d957600080fd5b5060c9546001600160a01b0316610175565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361023c5760405162461bcd60e51b815260040161023390610dd1565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610285600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b0316146102ab5760405162461bcd60e51b815260040161023390610e1d565b6102b481610678565b604080516000808252602082019092526102d091839190610680565b50565b6102db6107f0565b6102e361084f565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361032d5760405162461bcd60e51b815260040161023390610dd1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610376600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b03161461039c5760405162461bcd60e51b815260040161023390610e1d565b6103a582610678565b6103b182826001610680565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104555760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610233565b50600080516020610f5e83398151915290565b6104706107f0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610233565b6104a66107f0565b6102e36108a1565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156104f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051c9190610e69565b905090565b600054610100900460ff16158080156105415750600054600160ff909116105b8061055b5750303b15801561055b575060005460ff166001145b6105be5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610233565b6000805460ff1916600117905580156105e1576000805461ff0019166101001790555b6105ea826108de565b6105f261090e565b6105fa61093d565b80156103b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61064b6107f0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610233565b6102d06107f0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106b8576106b383610964565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610712575060408051601f3d908101601f1916820190925261070f91810190610e86565b60015b6107755760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610233565b600080516020610f5e83398151915281146107e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610233565b506106b3838383610a00565b336107f96104ae565b6001600160a01b0316146102e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610233565b610857610a2b565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6108a9610a74565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586108843390565b600054610100900460ff166109055760405162461bcd60e51b815260040161023390610e9f565b6102d081610aba565b600054610100900460ff166109355760405162461bcd60e51b815260040161023390610e9f565b6102e3610b03565b600054610100900460ff166102e35760405162461bcd60e51b815260040161023390610e9f565b6001600160a01b0381163b6109d15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610233565b600080516020610f5e83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0983610b36565b600082511180610a165750805b156106b357610a258383610b76565b50505050565b60fc5460ff166102e35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610233565b60fc5460ff16156102e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610233565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161023390610e9f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610b2a5760405162461bcd60e51b815260040161023390610e9f565b60fc805460ff19169055565b610b3f81610964565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b9b8383604051806060016040528060278152602001610f7e60279139610ba2565b9392505050565b6060600080856001600160a01b031685604051610bbf9190610f0e565b600060405180830381855af49150503d8060008114610bfa576040519150601f19603f3d011682016040523d82523d6000602084013e610bff565b606091505b5091509150610c1086838387610c1a565b9695505050505050565b60608315610c89578251600003610c82576001600160a01b0385163b610c825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610233565b5081610c93565b610c938383610c9b565b949350505050565b815115610cab5781518083602001fd5b8060405162461bcd60e51b81526004016102339190610f2a565b6001600160a01b03811681146102d057600080fd5b600060208284031215610cec57600080fd5b8135610b9b81610cc5565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610d2057600080fd5b8235610d2b81610cc5565b9150602083013567ffffffffffffffff80821115610d4857600080fd5b818501915085601f830112610d5c57600080fd5b813581811115610d6e57610d6e610cf7565b604051601f8201601f19908116603f01168101908382118183101715610d9657610d96610cf7565b81604052828152886020848701011115610daf57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e7b57600080fd5b8151610b9b81610cc5565b600060208284031215610e9857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610f05578181015183820152602001610eed565b50506000910152565b60008251610f20818460208701610eea565b9190910192915050565b6020815260008251806020840152610f49816040850160208701610eea565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220aab01cd1ef87511bdcf5881d65cc7a80575fe7bc002be4ffbe4a723f3f98b83464736f6c63430008120033", - "deployedBytecode": "0x60806040526004361061009c5760003560e01c8063715018a611610064578063715018a6146101365780638456cb591461014b5780638da5cb5b14610160578063c4d66de81461018d578063f2fde38b146101ad578063f762e734146101cd57600080fd5b80633659cfe6146100a15780633f4ba83a146100c35780634f1ef286146100d857806352d1902d146100eb5780635c975abb14610113575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610cda565b6101eb565b005b3480156100cf57600080fd5b506100c16102d3565b6100c16100e6366004610d0d565b6102e5565b3480156100f757600080fd5b506101006103b5565b6040519081526020015b60405180910390f35b34801561011f57600080fd5b5060fc5460ff16604051901515815260200161010a565b34801561014257600080fd5b506100c1610468565b34801561015757600080fd5b506100c161049e565b34801561016c57600080fd5b506101756104ae565b6040516001600160a01b03909116815260200161010a565b34801561019957600080fd5b506100c16101a8366004610cda565b610521565b3480156101b957600080fd5b506100c16101c8366004610cda565b610643565b3480156101d957600080fd5b5060c9546001600160a01b0316610175565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361023c5760405162461bcd60e51b815260040161023390610dd1565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610285600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b0316146102ab5760405162461bcd60e51b815260040161023390610e1d565b6102b481610678565b604080516000808252602082019092526102d091839190610680565b50565b6102db6107f0565b6102e361084f565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361032d5760405162461bcd60e51b815260040161023390610dd1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610376600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b03161461039c5760405162461bcd60e51b815260040161023390610e1d565b6103a582610678565b6103b182826001610680565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104555760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610233565b50600080516020610f5e83398151915290565b6104706107f0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610233565b6104a66107f0565b6102e36108a1565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156104f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051c9190610e69565b905090565b600054610100900460ff16158080156105415750600054600160ff909116105b8061055b5750303b15801561055b575060005460ff166001145b6105be5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610233565b6000805460ff1916600117905580156105e1576000805461ff0019166101001790555b6105ea826108de565b6105f261090e565b6105fa61093d565b80156103b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61064b6107f0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610233565b6102d06107f0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106b8576106b383610964565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610712575060408051601f3d908101601f1916820190925261070f91810190610e86565b60015b6107755760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610233565b600080516020610f5e83398151915281146107e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610233565b506106b3838383610a00565b336107f96104ae565b6001600160a01b0316146102e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610233565b610857610a2b565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6108a9610a74565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586108843390565b600054610100900460ff166109055760405162461bcd60e51b815260040161023390610e9f565b6102d081610aba565b600054610100900460ff166109355760405162461bcd60e51b815260040161023390610e9f565b6102e3610b03565b600054610100900460ff166102e35760405162461bcd60e51b815260040161023390610e9f565b6001600160a01b0381163b6109d15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610233565b600080516020610f5e83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0983610b36565b600082511180610a165750805b156106b357610a258383610b76565b50505050565b60fc5460ff166102e35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610233565b60fc5460ff16156102e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610233565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161023390610e9f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610b2a5760405162461bcd60e51b815260040161023390610e9f565b60fc805460ff19169055565b610b3f81610964565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b9b8383604051806060016040528060278152602001610f7e60279139610ba2565b9392505050565b6060600080856001600160a01b031685604051610bbf9190610f0e565b600060405180830381855af49150503d8060008114610bfa576040519150601f19603f3d011682016040523d82523d6000602084013e610bff565b606091505b5091509150610c1086838387610c1a565b9695505050505050565b60608315610c89578251600003610c82576001600160a01b0385163b610c825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610233565b5081610c93565b610c938383610c9b565b949350505050565b815115610cab5781518083602001fd5b8060405162461bcd60e51b81526004016102339190610f2a565b6001600160a01b03811681146102d057600080fd5b600060208284031215610cec57600080fd5b8135610b9b81610cc5565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610d2057600080fd5b8235610d2b81610cc5565b9150602083013567ffffffffffffffff80821115610d4857600080fd5b818501915085601f830112610d5c57600080fd5b813581811115610d6e57610d6e610cf7565b604051601f8201601f19908116603f01168101908382118183101715610d9657610d96610cf7565b81604052828152886020848701011115610daf57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e7b57600080fd5b8151610b9b81610cc5565b600060208284031215610e9857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610f05578181015183820152602001610eed565b50506000910152565b60008251610f20818460208701610eea565b9190910192915050565b6020815260008251806020840152610f49816040850160208701610eea565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220aab01cd1ef87511bdcf5881d65cc7a80575fe7bc002be4ffbe4a723f3f98b83464736f6c63430008120033", + "solcInputHash": "1c94255f5edec71501da736e9b19ae5f", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Specifically, some contracts within the codebase inherit from the GlobalPausableUpgradeable abstract contract. This provides them with an overriden paused() function that retrieves the pause state from this contract instead.For further details, see \\\"GlobalPause\\\" section of whitepaper.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalOwner_\":\"The address of the GlobalOwner contract.\"}},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"pause()\":{\"details\":\"Public implementation of PausableUpgradeable's pausing and unpausing functions but restricted to contract's owner.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"GlobalPause\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"}},\"notice\":\"Holds a global pause state shared by all contracts of the Ledgity Yield codebase.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GlobalPause.sol\":\"GlobalPause\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xa3b880c4d82e796c162c99a398b569ce4a8e6d27232014b81a6a4503718f12dc\",\"license\":\"MIT\"},\"contracts/src/GlobalPause.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalPause\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds a global pause state shared by all contracts of the Ledgity Yield\\n * codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\\n * paused() function that retrieves the pause state from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalPause\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalPause is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n PausableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\\n * but restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n}\\n\",\"keccak256\":\"0x9a0767e761dbd1d5800db03558c3903f229e6ef29f5fe5ff38f45fb4d7572e2e\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure:\\n * The _globalOwner state must be set at initialization time and, for evident security\\n * reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9203f7a2a19def126d8ff0fde8357053ffcf1100d65ec8faec8299b6ed2c0c5a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610fda610118600039600081816101f50152818161023e015281816102ef0152818161032f01526103c20152610fda6000f3fe60806040526004361061009c5760003560e01c8063715018a611610064578063715018a6146101365780638456cb591461014b5780638da5cb5b14610160578063c4d66de81461018d578063f2fde38b146101ad578063f762e734146101cd57600080fd5b80633659cfe6146100a15780633f4ba83a146100c35780634f1ef286146100d857806352d1902d146100eb5780635c975abb14610113575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610cda565b6101eb565b005b3480156100cf57600080fd5b506100c16102d3565b6100c16100e6366004610d0d565b6102e5565b3480156100f757600080fd5b506101006103b5565b6040519081526020015b60405180910390f35b34801561011f57600080fd5b5060fc5460ff16604051901515815260200161010a565b34801561014257600080fd5b506100c1610468565b34801561015757600080fd5b506100c161049e565b34801561016c57600080fd5b506101756104ae565b6040516001600160a01b03909116815260200161010a565b34801561019957600080fd5b506100c16101a8366004610cda565b610521565b3480156101b957600080fd5b506100c16101c8366004610cda565b610643565b3480156101d957600080fd5b5060c9546001600160a01b0316610175565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361023c5760405162461bcd60e51b815260040161023390610dd1565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610285600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b0316146102ab5760405162461bcd60e51b815260040161023390610e1d565b6102b481610678565b604080516000808252602082019092526102d091839190610680565b50565b6102db6107f0565b6102e361084f565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361032d5760405162461bcd60e51b815260040161023390610dd1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610376600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b03161461039c5760405162461bcd60e51b815260040161023390610e1d565b6103a582610678565b6103b182826001610680565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104555760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610233565b50600080516020610f5e83398151915290565b6104706107f0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610233565b6104a66107f0565b6102e36108a1565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156104f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051c9190610e69565b905090565b600054610100900460ff16158080156105415750600054600160ff909116105b8061055b5750303b15801561055b575060005460ff166001145b6105be5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610233565b6000805460ff1916600117905580156105e1576000805461ff0019166101001790555b6105ea826108de565b6105f261090e565b6105fa61093d565b80156103b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61064b6107f0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610233565b6102d06107f0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106b8576106b383610964565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610712575060408051601f3d908101601f1916820190925261070f91810190610e86565b60015b6107755760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610233565b600080516020610f5e83398151915281146107e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610233565b506106b3838383610a00565b336107f96104ae565b6001600160a01b0316146102e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610233565b610857610a2b565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6108a9610a74565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586108843390565b600054610100900460ff166109055760405162461bcd60e51b815260040161023390610e9f565b6102d081610aba565b600054610100900460ff166109355760405162461bcd60e51b815260040161023390610e9f565b6102e3610b03565b600054610100900460ff166102e35760405162461bcd60e51b815260040161023390610e9f565b6001600160a01b0381163b6109d15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610233565b600080516020610f5e83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0983610b36565b600082511180610a165750805b156106b357610a258383610b76565b50505050565b60fc5460ff166102e35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610233565b60fc5460ff16156102e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610233565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161023390610e9f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610b2a5760405162461bcd60e51b815260040161023390610e9f565b60fc805460ff19169055565b610b3f81610964565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b9b8383604051806060016040528060278152602001610f7e60279139610ba2565b9392505050565b6060600080856001600160a01b031685604051610bbf9190610f0e565b600060405180830381855af49150503d8060008114610bfa576040519150601f19603f3d011682016040523d82523d6000602084013e610bff565b606091505b5091509150610c1086838387610c1a565b9695505050505050565b60608315610c89578251600003610c82576001600160a01b0385163b610c825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610233565b5081610c93565b610c938383610c9b565b949350505050565b815115610cab5781518083602001fd5b8060405162461bcd60e51b81526004016102339190610f2a565b6001600160a01b03811681146102d057600080fd5b600060208284031215610cec57600080fd5b8135610b9b81610cc5565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610d2057600080fd5b8235610d2b81610cc5565b9150602083013567ffffffffffffffff80821115610d4857600080fd5b818501915085601f830112610d5c57600080fd5b813581811115610d6e57610d6e610cf7565b604051601f8201601f19908116603f01168101908382118183101715610d9657610d96610cf7565b81604052828152886020848701011115610daf57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e7b57600080fd5b8151610b9b81610cc5565b600060208284031215610e9857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610f05578181015183820152602001610eed565b50506000910152565b60008251610f20818460208701610eea565b9190910192915050565b6020815260008251806020840152610f49816040850160208701610eea565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204b6850ce781cface9fdf0c166b79d65bd4bbb2d52856d077ee54eb215d1371b564736f6c63430008120033", + "deployedBytecode": "0x60806040526004361061009c5760003560e01c8063715018a611610064578063715018a6146101365780638456cb591461014b5780638da5cb5b14610160578063c4d66de81461018d578063f2fde38b146101ad578063f762e734146101cd57600080fd5b80633659cfe6146100a15780633f4ba83a146100c35780634f1ef286146100d857806352d1902d146100eb5780635c975abb14610113575b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610cda565b6101eb565b005b3480156100cf57600080fd5b506100c16102d3565b6100c16100e6366004610d0d565b6102e5565b3480156100f757600080fd5b506101006103b5565b6040519081526020015b60405180910390f35b34801561011f57600080fd5b5060fc5460ff16604051901515815260200161010a565b34801561014257600080fd5b506100c1610468565b34801561015757600080fd5b506100c161049e565b34801561016c57600080fd5b506101756104ae565b6040516001600160a01b03909116815260200161010a565b34801561019957600080fd5b506100c16101a8366004610cda565b610521565b3480156101b957600080fd5b506100c16101c8366004610cda565b610643565b3480156101d957600080fd5b5060c9546001600160a01b0316610175565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361023c5760405162461bcd60e51b815260040161023390610dd1565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610285600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b0316146102ab5760405162461bcd60e51b815260040161023390610e1d565b6102b481610678565b604080516000808252602082019092526102d091839190610680565b50565b6102db6107f0565b6102e361084f565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361032d5760405162461bcd60e51b815260040161023390610dd1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610376600080516020610f5e833981519152546001600160a01b031690565b6001600160a01b03161461039c5760405162461bcd60e51b815260040161023390610e1d565b6103a582610678565b6103b182826001610680565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104555760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610233565b50600080516020610f5e83398151915290565b6104706107f0565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610233565b6104a66107f0565b6102e36108a1565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156104f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051c9190610e69565b905090565b600054610100900460ff16158080156105415750600054600160ff909116105b8061055b5750303b15801561055b575060005460ff166001145b6105be5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610233565b6000805460ff1916600117905580156105e1576000805461ff0019166101001790555b6105ea826108de565b6105f261090e565b6105fa61093d565b80156103b1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61064b6107f0565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610233565b6102d06107f0565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156106b8576106b383610964565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610712575060408051601f3d908101601f1916820190925261070f91810190610e86565b60015b6107755760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610233565b600080516020610f5e83398151915281146107e45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610233565b506106b3838383610a00565b336107f96104ae565b6001600160a01b0316146102e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610233565b610857610a2b565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6108a9610a74565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586108843390565b600054610100900460ff166109055760405162461bcd60e51b815260040161023390610e9f565b6102d081610aba565b600054610100900460ff166109355760405162461bcd60e51b815260040161023390610e9f565b6102e3610b03565b600054610100900460ff166102e35760405162461bcd60e51b815260040161023390610e9f565b6001600160a01b0381163b6109d15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610233565b600080516020610f5e83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b610a0983610b36565b600082511180610a165750805b156106b357610a258383610b76565b50505050565b60fc5460ff166102e35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610233565b60fc5460ff16156102e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610233565b600054610100900460ff16610ae15760405162461bcd60e51b815260040161023390610e9f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16610b2a5760405162461bcd60e51b815260040161023390610e9f565b60fc805460ff19169055565b610b3f81610964565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060610b9b8383604051806060016040528060278152602001610f7e60279139610ba2565b9392505050565b6060600080856001600160a01b031685604051610bbf9190610f0e565b600060405180830381855af49150503d8060008114610bfa576040519150601f19603f3d011682016040523d82523d6000602084013e610bff565b606091505b5091509150610c1086838387610c1a565b9695505050505050565b60608315610c89578251600003610c82576001600160a01b0385163b610c825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610233565b5081610c93565b610c938383610c9b565b949350505050565b815115610cab5781518083602001fd5b8060405162461bcd60e51b81526004016102339190610f2a565b6001600160a01b03811681146102d057600080fd5b600060208284031215610cec57600080fd5b8135610b9b81610cc5565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610d2057600080fd5b8235610d2b81610cc5565b9150602083013567ffffffffffffffff80821115610d4857600080fd5b818501915085601f830112610d5c57600080fd5b813581811115610d6e57610d6e610cf7565b604051601f8201601f19908116603f01168101908382118183101715610d9657610d96610cf7565b81604052828152886020848701011115610daf57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610e7b57600080fd5b8151610b9b81610cc5565b600060208284031215610e9857600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610f05578181015183820152602001610eed565b50506000910152565b60008251610f20818460208701610eea565b9190910192915050565b6020815260008251806020840152610f49816040850160208701610eea565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204b6850ce781cface9fdf0c166b79d65bd4bbb2d52856d077ee54eb215d1371b564736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", @@ -364,7 +364,7 @@ "notice": "Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there." } }, - "notice": "Maintains a global pause state shared by all contracts of the Ledgity Yield codebase.", + "notice": "Holds a global pause state shared by all contracts of the Ledgity Yield codebase.", "version": 1 }, "storageLayout": { @@ -426,15 +426,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7671, + "astId": 7770, "contract": "contracts/src/GlobalPause.sol:GlobalPause", "label": "_globalOwner", "offset": 0, "slot": "201", - "type": "t_contract(GlobalOwner)4909" + "type": "t_contract(GlobalOwner)4973" }, { - "astId": 7755, + "astId": 7854, "contract": "contracts/src/GlobalPause.sol:GlobalPause", "label": "__gap", "offset": 0, @@ -481,7 +481,7 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(GlobalOwner)4909": { + "t_contract(GlobalOwner)4973": { "encoding": "inplace", "label": "contract GlobalOwner", "numberOfBytes": "20" diff --git a/contracts/hardhat/deployments/localhost/GlobalPause_Proxy.json b/contracts/hardhat/deployments/localhost/GlobalPause_Proxy.json index f7a672fa..f5762989 100644 --- a/contracts/hardhat/deployments/localhost/GlobalPause_Proxy.json +++ b/contracts/hardhat/deployments/localhost/GlobalPause_Proxy.json @@ -79,7 +79,7 @@ "transactionIndex": 0, "gasUsed": "335171", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000400000000080000400000000000000000000000000001000000000000000000000000000002000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3", + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038", "transactionHash": "0x5553bb49f49e690220e8077b3bf6fd1f8a403d84d29402f881adf2be52fd542f", "logs": [ { @@ -93,7 +93,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3" + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038" }, { "transactionIndex": 0, @@ -105,7 +105,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0xdc6c15d9ded2f8ba15ebce3c00673c7b9eeb1c9ddceadad4fb3337af053b38c3" + "blockHash": "0x93079c5b76d87c21d6c9043eaa8ed4881019270e5669df8e60ed5ab38a8df038" } ], "blockNumber": 4, diff --git a/contracts/hardhat/deployments/localhost/LDYStaking.json b/contracts/hardhat/deployments/localhost/LDYStaking.json index 212e6a2c..bc439029 100644 --- a/contracts/hardhat/deployments/localhost/LDYStaking.json +++ b/contracts/hardhat/deployments/localhost/LDYStaking.json @@ -149,7 +149,7 @@ "type": "function" } ], - "transactionHash": "0x42e443c5d86853c1ec4739bf599962a7b04274ff7887cb381c75bf7c2384c83b", + "transactionHash": "0x044133e46033be664ddaa781c1f9387f7b1de8233267e1092c07e658d167a5ec", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", @@ -157,13 +157,13 @@ "transactionIndex": 0, "gasUsed": "312711", "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000010000000000000000000000020000000000000100000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x776cc11819b923012dfac01270283480c153cefce4d55147d50c5d641d187d19", - "transactionHash": "0x42e443c5d86853c1ec4739bf599962a7b04274ff7887cb381c75bf7c2384c83b", + "blockHash": "0x356c689f13361090c98189ce952ab62741bc0151a0d4d4b09eb424efac766f42", + "transactionHash": "0x044133e46033be664ddaa781c1f9387f7b1de8233267e1092c07e658d167a5ec", "logs": [ { "transactionIndex": 0, "blockNumber": 8, - "transactionHash": "0x42e443c5d86853c1ec4739bf599962a7b04274ff7887cb381c75bf7c2384c83b", + "transactionHash": "0x044133e46033be664ddaa781c1f9387f7b1de8233267e1092c07e658d167a5ec", "address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", @@ -172,7 +172,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x776cc11819b923012dfac01270283480c153cefce4d55147d50c5d641d187d19" + "blockHash": "0x356c689f13361090c98189ce952ab62741bc0151a0d4d4b09eb424efac766f42" } ], "blockNumber": 8, @@ -182,10 +182,10 @@ }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"highTierAccounts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"setHighTierAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"tierOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"tier\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"This contract only implements tierOf() function from LDYStaking as it's the only one the LToken contract relies on.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setHighTierAccount(address,bool)\":{\"params\":{\"account\":\"The account to update the high tier status of.\"}},\"tierOf(address)\":{\"details\":\"Dummy tierOf() function that always return that the given account is not ellgible to any LDY staking tier, except if the account is in the defaultToHighestTier mapping.\",\"params\":{\"account\":\"The account to check the tier of.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"highTierAccounts\":{\"details\":\"This is notably used to allow PreMining contracts to benefit from 0% withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\"}},\"title\":\"LDYStaking\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"highTierAccounts(address)\":{\"notice\":\"Holds a mapping of addresses that default to the highest staking tier.\"},\"setHighTierAccount(address,bool)\":{\"notice\":\"Update high tier status of a given account.\"}},\"notice\":\"Replacement to the LDYStaking contract until the $LDY token is available and the real LDYStaking can be deployed.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/DummyLDYStaking.sol\":\"LDYStaking\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Replacement to the LDYStaking contract until the $LDY token is available and\\n * the real LDYStaking can be deployed.\\n *\\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\\n * one the LToken contract relies on.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LDYStaking is Ownable2Step {\\n /**\\n * @notice Holds a mapping of addresses that default to the highest staking tier.\\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\\n */\\n mapping(address => bool) public highTierAccounts;\\n\\n /**\\n * @notice Update high tier status of a given account.\\n * @param account The account to update the high tier status of.\\n */\\n function setHighTierAccount(address account, bool status) external onlyOwner {\\n highTierAccounts[account] = status;\\n }\\n\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * ellgible to any LDY staking tier, except if the account is in the\\n * defaultToHighestTier mapping.\\n * @param account The account to check the tier of.\\n */\\n function tierOf(address account) public view returns (uint256 tier) {\\n if (highTierAccounts[account]) return 3;\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x5d1fd1821e7d5d6cac7424373eb5cbfeebe6a075f897c7f62fb30241ea5b6309\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b610096565b600180546001600160a01b031916905561004381610046602090811b6102bc17901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61042f806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063c66120f41161005b578063c66120f4146100dc578063c8f74bb81461010f578063e30c397814610130578063f2fde38b1461014157600080fd5b80634c1fa4b91461008d578063715018a6146100a257806379ba5097146100aa5780638da5cb5b146100b2575b600080fd5b6100a061009b36600461039b565b610154565b005b6100a0610187565b6100a061019b565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100ff6100ea3660046103d7565b60026020526000908152604090205460ff1681565b60405190151581526020016100d3565b61012261011d3660046103d7565b61021a565b6040519081526020016100d3565b6001546001600160a01b03166100bf565b6100a061014f3660046103d7565b61024b565b61015c61030c565b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b61018f61030c565b6101996000610366565b565b60015433906001600160a01b0316811461020e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61021781610366565b50565b6001600160a01b03811660009081526002602052604081205460ff161561024357506003919050565b506000919050565b61025361030c565b600180546001600160a01b0383166001600160a01b031990911681179091556102846000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610205565b600180546001600160a01b0319169055610217816102bc565b80356001600160a01b038116811461039657600080fd5b919050565b600080604083850312156103ae57600080fd5b6103b78361037f565b9150602083013580151581146103cc57600080fd5b809150509250929050565b6000602082840312156103e957600080fd5b6103f28261037f565b939250505056fea2646970667358221220e3a758ea7167ac5af8596a0b9fc13f7410e9a32f0c9bd3c4a2c0e69111bfe95664736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063c66120f41161005b578063c66120f4146100dc578063c8f74bb81461010f578063e30c397814610130578063f2fde38b1461014157600080fd5b80634c1fa4b91461008d578063715018a6146100a257806379ba5097146100aa5780638da5cb5b146100b2575b600080fd5b6100a061009b36600461039b565b610154565b005b6100a0610187565b6100a061019b565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100ff6100ea3660046103d7565b60026020526000908152604090205460ff1681565b60405190151581526020016100d3565b61012261011d3660046103d7565b61021a565b6040519081526020016100d3565b6001546001600160a01b03166100bf565b6100a061014f3660046103d7565b61024b565b61015c61030c565b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b61018f61030c565b6101996000610366565b565b60015433906001600160a01b0316811461020e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61021781610366565b50565b6001600160a01b03811660009081526002602052604081205460ff161561024357506003919050565b506000919050565b61025361030c565b600180546001600160a01b0383166001600160a01b031990911681179091556102846000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610205565b600180546001600160a01b0319169055610217816102bc565b80356001600160a01b038116811461039657600080fd5b919050565b600080604083850312156103ae57600080fd5b6103b78361037f565b9150602083013580151581146103cc57600080fd5b809150509250929050565b6000602082840312156103e957600080fd5b6103f28261037f565b939250505056fea2646970667358221220e3a758ea7167ac5af8596a0b9fc13f7410e9a32f0c9bd3c4a2c0e69111bfe95664736f6c63430008120033", + "solcInputHash": "1c94255f5edec71501da736e9b19ae5f", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"highTierAccounts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"setHighTierAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"tierOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"tier\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"This contract only implements tierOf() function from LDYStaking as it's the only one the LToken contract relies on.\",\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setHighTierAccount(address,bool)\":{\"params\":{\"account\":\"The account to update the high tier status of.\"}},\"tierOf(address)\":{\"details\":\"Dummy tierOf() function that always return that the given account is not elligible to any LDY staking tier, except if the account is in the highTierAccounts mapping.\",\"params\":{\"account\":\"The account to check the tier of.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"stateVariables\":{\"highTierAccounts\":{\"details\":\"This is notably used to allow PreMining contracts to benefit from 0% withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\"}},\"title\":\"LDYStaking\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"highTierAccounts(address)\":{\"notice\":\"Holds a mapping of addresses that default to the highest staking tier.\"},\"setHighTierAccount(address,bool)\":{\"notice\":\"Update high tier status of a given account.\"}},\"notice\":\"This contract acts as a placeholder for the real LDYStaking contract until this one is deployed.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/DummyLDYStaking.sol\":\"LDYStaking\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This contract acts as a placeholder for the real LDYStaking contract until\\n * this one is deployed.\\n *\\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\\n * one the LToken contract relies on.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LDYStaking is Ownable2Step {\\n /**\\n * @notice Holds a mapping of addresses that default to the highest staking tier.\\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\\n */\\n mapping(address => bool) public highTierAccounts;\\n\\n /**\\n * @notice Update high tier status of a given account.\\n * @param account The account to update the high tier status of.\\n */\\n function setHighTierAccount(address account, bool status) public onlyOwner {\\n highTierAccounts[account] = status;\\n }\\n\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * elligible to any LDY staking tier, except if the account is in the\\n * highTierAccounts mapping.\\n * @param account The account to check the tier of.\\n */\\n function tierOf(address account) public view returns (uint256 tier) {\\n if (highTierAccounts[account]) return 3;\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x7be21f1a748fedb7b8b873230e24be45922e8bc09e87147b980a0a596e7550db\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b610096565b600180546001600160a01b031916905561004381610046602090811b6102bc17901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61042f806100a56000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063c66120f41161005b578063c66120f4146100dc578063c8f74bb81461010f578063e30c397814610130578063f2fde38b1461014157600080fd5b80634c1fa4b91461008d578063715018a6146100a257806379ba5097146100aa5780638da5cb5b146100b2575b600080fd5b6100a061009b36600461039b565b610154565b005b6100a0610187565b6100a061019b565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100ff6100ea3660046103d7565b60026020526000908152604090205460ff1681565b60405190151581526020016100d3565b61012261011d3660046103d7565b61021a565b6040519081526020016100d3565b6001546001600160a01b03166100bf565b6100a061014f3660046103d7565b61024b565b61015c61030c565b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b61018f61030c565b6101996000610366565b565b60015433906001600160a01b0316811461020e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61021781610366565b50565b6001600160a01b03811660009081526002602052604081205460ff161561024357506003919050565b506000919050565b61025361030c565b600180546001600160a01b0383166001600160a01b031990911681179091556102846000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610205565b600180546001600160a01b0319169055610217816102bc565b80356001600160a01b038116811461039657600080fd5b919050565b600080604083850312156103ae57600080fd5b6103b78361037f565b9150602083013580151581146103cc57600080fd5b809150509250929050565b6000602082840312156103e957600080fd5b6103f28261037f565b939250505056fea26469706673582212206538dd1589f64b8126522536a9b40ae8df1cd7f3b00b0c6919dcdbdbac49569f64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063c66120f41161005b578063c66120f4146100dc578063c8f74bb81461010f578063e30c397814610130578063f2fde38b1461014157600080fd5b80634c1fa4b91461008d578063715018a6146100a257806379ba5097146100aa5780638da5cb5b146100b2575b600080fd5b6100a061009b36600461039b565b610154565b005b6100a0610187565b6100a061019b565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6100ff6100ea3660046103d7565b60026020526000908152604090205460ff1681565b60405190151581526020016100d3565b61012261011d3660046103d7565b61021a565b6040519081526020016100d3565b6001546001600160a01b03166100bf565b6100a061014f3660046103d7565b61024b565b61015c61030c565b6001600160a01b03919091166000908152600260205260409020805460ff1916911515919091179055565b61018f61030c565b6101996000610366565b565b60015433906001600160a01b0316811461020e5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61021781610366565b50565b6001600160a01b03811660009081526002602052604081205460ff161561024357506003919050565b506000919050565b61025361030c565b600180546001600160a01b0383166001600160a01b031990911681179091556102846000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b031633146101995760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610205565b600180546001600160a01b0319169055610217816102bc565b80356001600160a01b038116811461039657600080fd5b919050565b600080604083850312156103ae57600080fd5b6103b78361037f565b9150602083013580151581146103cc57600080fd5b809150509250929050565b6000602082840312156103e957600080fd5b6103f28261037f565b939250505056fea26469706673582212206538dd1589f64b8126522536a9b40ae8df1cd7f3b00b0c6919dcdbdbac49569f64736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", @@ -210,7 +210,7 @@ } }, "tierOf(address)": { - "details": "Dummy tierOf() function that always return that the given account is not ellgible to any LDY staking tier, except if the account is in the defaultToHighestTier mapping.", + "details": "Dummy tierOf() function that always return that the given account is not elligible to any LDY staking tier, except if the account is in the highTierAccounts mapping.", "params": { "account": "The account to check the tier of." } @@ -237,7 +237,7 @@ "notice": "Update high tier status of a given account." } }, - "notice": "Replacement to the LDYStaking contract until the $LDY token is available and the real LDYStaking can be deployed.", + "notice": "This contract acts as a placeholder for the real LDYStaking contract until this one is deployed.", "version": 1 }, "storageLayout": { diff --git a/contracts/hardhat/deployments/localhost/LTokenSignaler.json b/contracts/hardhat/deployments/localhost/LTokenSignaler.json index cf9c8e28..a9f23066 100644 --- a/contracts/hardhat/deployments/localhost/LTokenSignaler.json +++ b/contracts/hardhat/deployments/localhost/LTokenSignaler.json @@ -240,7 +240,7 @@ "transactionIndex": 0, "gasUsed": "332615", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000400000000000", - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520", + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927", "transactionHash": "0x0f8861522017b913a03fb6042639ed4b27740c20b210b6a14823edf3ebdccbd4", "logs": [ { @@ -254,7 +254,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520" + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927" }, { "transactionIndex": 0, @@ -266,7 +266,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520" + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927" } ], "blockNumber": 13, diff --git a/contracts/hardhat/deployments/localhost/LTokenSignaler_Implementation.json b/contracts/hardhat/deployments/localhost/LTokenSignaler_Implementation.json index f7cad291..198e0980 100644 --- a/contracts/hardhat/deployments/localhost/LTokenSignaler_Implementation.json +++ b/contracts/hardhat/deployments/localhost/LTokenSignaler_Implementation.json @@ -213,7 +213,7 @@ "type": "function" } ], - "transactionHash": "0x3b04ad55820952f2b12a6b8a8d2556a89e55ae2fed27d5795f47ed950bf92273", + "transactionHash": "0xc3c8146080dff66cbe3487f88b57925ea8e5f92793e505e73215e5441e20fc0f", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", @@ -221,20 +221,20 @@ "transactionIndex": 0, "gasUsed": "862865", "logsBloom": "0x00000000100000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbda7ba18860c66652317c51fbc57d1bc8a90385e2414909d605a5717001deb41", - "transactionHash": "0x3b04ad55820952f2b12a6b8a8d2556a89e55ae2fed27d5795f47ed950bf92273", + "blockHash": "0x4ed1cef84d62586e8e3a4325d0375fe00a9d3e120200b76074ed6ba429b38f02", + "transactionHash": "0xc3c8146080dff66cbe3487f88b57925ea8e5f92793e505e73215e5441e20fc0f", "logs": [ { "transactionIndex": 0, "blockNumber": 12, - "transactionHash": "0x3b04ad55820952f2b12a6b8a8d2556a89e55ae2fed27d5795f47ed950bf92273", + "transactionHash": "0xc3c8146080dff66cbe3487f88b57925ea8e5f92793e505e73215e5441e20fc0f", "address": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0xbda7ba18860c66652317c51fbc57d1bc8a90385e2414909d605a5717001deb41" + "blockHash": "0x4ed1cef84d62586e8e3a4325d0375fe00a9d3e120200b76074ed6ba429b38f02" } ], "blockNumber": 12, @@ -244,10 +244,10 @@ }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"lTokenAddress\",\"type\":\"address\"}],\"name\":\"LTokenSignalEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"lTokenAddress\",\"type\":\"address\"}],\"name\":\"signalLToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Signal are ignored by the subgraph if the L-Token is already known by it.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"LTokenSignalEvent(address)\":{\"params\":{\"lTokenAddress\":\"The address of the L-Token contract to signal.\"}},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\"},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"signalLToken(address)\":{\"params\":{\"lTokenAddress\":\"The address of the LToken contract to signal.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"LTokenSignaler\",\"version\":1},\"userdoc\":{\"events\":{\"LTokenSignalEvent(address)\":{\"notice\":\"Emitted to inform subgraph of the existence of a new L-Token contract.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"signalLToken(address)\":{\"notice\":\"Signals a LToken contract to the TheGraph subgraph of the current chain.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"}},\"notice\":\"Used to inform subgraph from the existence of a new L-Token contract. Once signaled, a L-Token it will start being indexed.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/LTokenSignaler.sol\":\"LTokenSignaler\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"},\"contracts/src/LTokenSignaler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title LTokenSignaler\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Used to inform subgraph from the existence of a new L-Token contract. Once\\n * signaled, a L-Token it will start being indexed.\\n *\\n * @dev Signal are ignored by the subgraph if the L-Token is already known by it.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LTokenSignaler is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Emitted to inform subgraph of the existence of a new L-Token contract.\\n * @param lTokenAddress The address of the L-Token contract to signal.\\n */\\n event LTokenSignalEvent(address indexed lTokenAddress);\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Signals a LToken contract to the TheGraph subgraph of the current chain.\\n * @param lTokenAddress The address of the LToken contract to signal.\\n */\\n function signalLToken(address lTokenAddress) external onlyOwner {\\n // Signal the LToken contract\\n emit LTokenSignalEvent(lTokenAddress);\\n }\\n}\\n\",\"keccak256\":\"0x3463d89aa59ae2c6efcbbba9a2b0328551a161129b3e127b9cb9833d281f4a5b\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x59c14d38e9e96d4f60cf2fd626c56e23928fce85107ac8d603dfdb90c9d81ec4\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610e2e610118600039600081816101b2015281816101fb0152818161029a015281816102da015261036d0152610e2e6000f3fe6080604052600436106100865760003560e01c80638da5cb5b116100595780638da5cb5b146100fd578063a69823dc1461012a578063c4d66de81461014a578063f2fde38b1461016a578063f762e7341461018a57600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b2e565b6101a8565b005b6100ab6100bb366004610b61565b610290565b3480156100cc57600080fd5b506100d5610360565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610413565b34801561010957600080fd5b50610112610449565b6040516001600160a01b0390911681526020016100df565b34801561013657600080fd5b506100ab610145366004610b2e565b6104bc565b34801561015657600080fd5b506100ab610165366004610b2e565b6104fb565b34801561017657600080fd5b506100ab610185366004610b2e565b610615565b34801561019657600080fd5b5060c9546001600160a01b0316610112565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101f95760405162461bcd60e51b81526004016101f090610c25565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610242600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146102685760405162461bcd60e51b81526004016101f090610c71565b6102718161064a565b6040805160008082526020820190925261028d91839190610652565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102d85760405162461bcd60e51b81526004016101f090610c25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610321600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146103475760405162461bcd60e51b81526004016101f090610c71565b6103508261064a565b61035c82826001610652565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101f0565b50600080516020610db283398151915290565b61041b6107c2565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016101f0565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190610cbd565b905090565b6104c46107c2565b6040516001600160a01b038216907f36c1488d5243eeaf5fb0cf28a35c54973316358b76e9c32ccbe2c57956b0879b90600090a250565b600054610100900460ff161580801561051b5750600054600160ff909116105b806105355750303b158015610535575060005460ff166001145b6105985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101f0565b6000805460ff1916600117905580156105bb576000805461ff0019166101001790555b6105c482610823565b6105cc610853565b801561035c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61061d6107c2565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016101f0565b61028d6107c2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561068a576106858361087a565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e4575060408051601f3d908101601f191682019092526106e191810190610cda565b60015b6107475760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101f0565b600080516020610db283398151915281146107b65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101f0565b50610685838383610916565b336107cb610449565b6001600160a01b0316146108215760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101f0565b565b600054610100900460ff1661084a5760405162461bcd60e51b81526004016101f090610cf3565b61028d81610941565b600054610100900460ff166108215760405162461bcd60e51b81526004016101f090610cf3565b6001600160a01b0381163b6108e75760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101f0565b600080516020610db283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61091f8361098a565b60008251118061092c5750805b156106855761093b83836109ca565b50505050565b600054610100900460ff166109685760405162461bcd60e51b81526004016101f090610cf3565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b6109938161087a565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606109ef8383604051806060016040528060278152602001610dd2602791396109f6565b9392505050565b6060600080856001600160a01b031685604051610a139190610d62565b600060405180830381855af49150503d8060008114610a4e576040519150601f19603f3d011682016040523d82523d6000602084013e610a53565b606091505b5091509150610a6486838387610a6e565b9695505050505050565b60608315610add578251600003610ad6576001600160a01b0385163b610ad65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f0565b5081610ae7565b610ae78383610aef565b949350505050565b815115610aff5781518083602001fd5b8060405162461bcd60e51b81526004016101f09190610d7e565b6001600160a01b038116811461028d57600080fd5b600060208284031215610b4057600080fd5b81356109ef81610b19565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b7457600080fd5b8235610b7f81610b19565b9150602083013567ffffffffffffffff80821115610b9c57600080fd5b818501915085601f830112610bb057600080fd5b813581811115610bc257610bc2610b4b565b604051601f8201601f19908116603f01168101908382118183101715610bea57610bea610b4b565b81604052828152886020848701011115610c0357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ccf57600080fd5b81516109ef81610b19565b600060208284031215610cec57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d59578181015183820152602001610d41565b50506000910152565b60008251610d74818460208701610d3e565b9190910192915050565b6020815260008251806020840152610d9d816040850160208701610d3e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220cdf21494e0717c404e4b8dea627a4bed4f7c3c39ab8ec161ab31857028c2258364736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106100865760003560e01c80638da5cb5b116100595780638da5cb5b146100fd578063a69823dc1461012a578063c4d66de81461014a578063f2fde38b1461016a578063f762e7341461018a57600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b2e565b6101a8565b005b6100ab6100bb366004610b61565b610290565b3480156100cc57600080fd5b506100d5610360565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610413565b34801561010957600080fd5b50610112610449565b6040516001600160a01b0390911681526020016100df565b34801561013657600080fd5b506100ab610145366004610b2e565b6104bc565b34801561015657600080fd5b506100ab610165366004610b2e565b6104fb565b34801561017657600080fd5b506100ab610185366004610b2e565b610615565b34801561019657600080fd5b5060c9546001600160a01b0316610112565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101f95760405162461bcd60e51b81526004016101f090610c25565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610242600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146102685760405162461bcd60e51b81526004016101f090610c71565b6102718161064a565b6040805160008082526020820190925261028d91839190610652565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102d85760405162461bcd60e51b81526004016101f090610c25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610321600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146103475760405162461bcd60e51b81526004016101f090610c71565b6103508261064a565b61035c82826001610652565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101f0565b50600080516020610db283398151915290565b61041b6107c2565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016101f0565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190610cbd565b905090565b6104c46107c2565b6040516001600160a01b038216907f36c1488d5243eeaf5fb0cf28a35c54973316358b76e9c32ccbe2c57956b0879b90600090a250565b600054610100900460ff161580801561051b5750600054600160ff909116105b806105355750303b158015610535575060005460ff166001145b6105985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101f0565b6000805460ff1916600117905580156105bb576000805461ff0019166101001790555b6105c482610823565b6105cc610853565b801561035c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61061d6107c2565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016101f0565b61028d6107c2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561068a576106858361087a565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e4575060408051601f3d908101601f191682019092526106e191810190610cda565b60015b6107475760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101f0565b600080516020610db283398151915281146107b65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101f0565b50610685838383610916565b336107cb610449565b6001600160a01b0316146108215760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101f0565b565b600054610100900460ff1661084a5760405162461bcd60e51b81526004016101f090610cf3565b61028d81610941565b600054610100900460ff166108215760405162461bcd60e51b81526004016101f090610cf3565b6001600160a01b0381163b6108e75760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101f0565b600080516020610db283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61091f8361098a565b60008251118061092c5750805b156106855761093b83836109ca565b50505050565b600054610100900460ff166109685760405162461bcd60e51b81526004016101f090610cf3565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b6109938161087a565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606109ef8383604051806060016040528060278152602001610dd2602791396109f6565b9392505050565b6060600080856001600160a01b031685604051610a139190610d62565b600060405180830381855af49150503d8060008114610a4e576040519150601f19603f3d011682016040523d82523d6000602084013e610a53565b606091505b5091509150610a6486838387610a6e565b9695505050505050565b60608315610add578251600003610ad6576001600160a01b0385163b610ad65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f0565b5081610ae7565b610ae78383610aef565b949350505050565b815115610aff5781518083602001fd5b8060405162461bcd60e51b81526004016101f09190610d7e565b6001600160a01b038116811461028d57600080fd5b600060208284031215610b4057600080fd5b81356109ef81610b19565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b7457600080fd5b8235610b7f81610b19565b9150602083013567ffffffffffffffff80821115610b9c57600080fd5b818501915085601f830112610bb057600080fd5b813581811115610bc257610bc2610b4b565b604051601f8201601f19908116603f01168101908382118183101715610bea57610bea610b4b565b81604052828152886020848701011115610c0357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ccf57600080fd5b81516109ef81610b19565b600060208284031215610cec57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d59578181015183820152602001610d41565b50506000910152565b60008251610d74818460208701610d3e565b9190910192915050565b6020815260008251806020840152610d9d816040850160208701610d3e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220cdf21494e0717c404e4b8dea627a4bed4f7c3c39ab8ec161ab31857028c2258364736f6c63430008120033", + "solcInputHash": "1c94255f5edec71501da736e9b19ae5f", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"lTokenAddress\",\"type\":\"address\"}],\"name\":\"LTokenSignalEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"lTokenAddress\",\"type\":\"address\"}],\"name\":\"signalLToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Signal are ignored by the subgraph if the L-Token is already known by it.\",\"events\":{\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"LTokenSignalEvent(address)\":{\"params\":{\"lTokenAddress\":\"The address of the L-Token contract to signal.\"}},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\"},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"initialize(address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\"},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"signalLToken(address)\":{\"params\":{\"lTokenAddress\":\"The address of the LToken contract to signal.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"}},\"title\":\"LTokenSignaler\",\"version\":1},\"userdoc\":{\"events\":{\"LTokenSignalEvent(address)\":{\"notice\":\"Emitted to inform subgraph of the existence of a new L-Token contract.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Prevents implementation contract from being initialized as recommended by OpenZeppelin.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"initialize(address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"signalLToken(address)\":{\"notice\":\"Signals a LToken contract to the TheGraph subgraph of the current chain.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"}},\"notice\":\"Used to inform subgraph from the existence of a new L-Token contract. Once signaled, a L-Token will start being indexed.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/LTokenSignaler.sol\":\"LTokenSignaler\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xa3b880c4d82e796c162c99a398b569ce4a8e6d27232014b81a6a4503718f12dc\",\"license\":\"MIT\"},\"contracts/src/LTokenSignaler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title LTokenSignaler\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Used to inform subgraph from the existence of a new L-Token contract. Once\\n * signaled, a L-Token will start being indexed.\\n *\\n * @dev Signal are ignored by the subgraph if the L-Token is already known by it.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LTokenSignaler is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Emitted to inform subgraph of the existence of a new L-Token contract.\\n * @param lTokenAddress The address of the L-Token contract to signal.\\n */\\n event LTokenSignalEvent(address indexed lTokenAddress);\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Signals a LToken contract to the TheGraph subgraph of the current chain.\\n * @param lTokenAddress The address of the LToken contract to signal.\\n */\\n function signalLToken(address lTokenAddress) external onlyOwner {\\n // Signal the LToken contract\\n emit LTokenSignalEvent(lTokenAddress);\\n }\\n}\\n\",\"keccak256\":\"0xdfbd3364c76705fb67b72cdb405d6691a9b2e3cbcc0f3f783add6ac6cc855bd3\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure:\\n * The _globalOwner state must be set at initialization time and, for evident security\\n * reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9203f7a2a19def126d8ff0fde8357053ffcf1100d65ec8faec8299b6ed2c0c5a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523060805234801561001457600080fd5b5061001d610022565b6100e1565b600054610100900460ff161561008e5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100df576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610e2e610118600039600081816101b2015281816101fb0152818161029a015281816102da015261036d0152610e2e6000f3fe6080604052600436106100865760003560e01c80638da5cb5b116100595780638da5cb5b146100fd578063a69823dc1461012a578063c4d66de81461014a578063f2fde38b1461016a578063f762e7341461018a57600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b2e565b6101a8565b005b6100ab6100bb366004610b61565b610290565b3480156100cc57600080fd5b506100d5610360565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610413565b34801561010957600080fd5b50610112610449565b6040516001600160a01b0390911681526020016100df565b34801561013657600080fd5b506100ab610145366004610b2e565b6104bc565b34801561015657600080fd5b506100ab610165366004610b2e565b6104fb565b34801561017657600080fd5b506100ab610185366004610b2e565b610615565b34801561019657600080fd5b5060c9546001600160a01b0316610112565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101f95760405162461bcd60e51b81526004016101f090610c25565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610242600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146102685760405162461bcd60e51b81526004016101f090610c71565b6102718161064a565b6040805160008082526020820190925261028d91839190610652565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102d85760405162461bcd60e51b81526004016101f090610c25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610321600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146103475760405162461bcd60e51b81526004016101f090610c71565b6103508261064a565b61035c82826001610652565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101f0565b50600080516020610db283398151915290565b61041b6107c2565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016101f0565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190610cbd565b905090565b6104c46107c2565b6040516001600160a01b038216907f36c1488d5243eeaf5fb0cf28a35c54973316358b76e9c32ccbe2c57956b0879b90600090a250565b600054610100900460ff161580801561051b5750600054600160ff909116105b806105355750303b158015610535575060005460ff166001145b6105985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101f0565b6000805460ff1916600117905580156105bb576000805461ff0019166101001790555b6105c482610823565b6105cc610853565b801561035c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61061d6107c2565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016101f0565b61028d6107c2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561068a576106858361087a565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e4575060408051601f3d908101601f191682019092526106e191810190610cda565b60015b6107475760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101f0565b600080516020610db283398151915281146107b65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101f0565b50610685838383610916565b336107cb610449565b6001600160a01b0316146108215760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101f0565b565b600054610100900460ff1661084a5760405162461bcd60e51b81526004016101f090610cf3565b61028d81610941565b600054610100900460ff166108215760405162461bcd60e51b81526004016101f090610cf3565b6001600160a01b0381163b6108e75760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101f0565b600080516020610db283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61091f8361098a565b60008251118061092c5750805b156106855761093b83836109ca565b50505050565b600054610100900460ff166109685760405162461bcd60e51b81526004016101f090610cf3565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b6109938161087a565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606109ef8383604051806060016040528060278152602001610dd2602791396109f6565b9392505050565b6060600080856001600160a01b031685604051610a139190610d62565b600060405180830381855af49150503d8060008114610a4e576040519150601f19603f3d011682016040523d82523d6000602084013e610a53565b606091505b5091509150610a6486838387610a6e565b9695505050505050565b60608315610add578251600003610ad6576001600160a01b0385163b610ad65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f0565b5081610ae7565b610ae78383610aef565b949350505050565b815115610aff5781518083602001fd5b8060405162461bcd60e51b81526004016101f09190610d7e565b6001600160a01b038116811461028d57600080fd5b600060208284031215610b4057600080fd5b81356109ef81610b19565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b7457600080fd5b8235610b7f81610b19565b9150602083013567ffffffffffffffff80821115610b9c57600080fd5b818501915085601f830112610bb057600080fd5b813581811115610bc257610bc2610b4b565b604051601f8201601f19908116603f01168101908382118183101715610bea57610bea610b4b565b81604052828152886020848701011115610c0357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ccf57600080fd5b81516109ef81610b19565b600060208284031215610cec57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d59578181015183820152602001610d41565b50506000910152565b60008251610d74818460208701610d3e565b9190910192915050565b6020815260008251806020840152610d9d816040850160208701610d3e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122068da0230acd1366802db80aa8fbec2cdf9b29855484e88bbd5526025431b168464736f6c63430008120033", + "deployedBytecode": "0x6080604052600436106100865760003560e01c80638da5cb5b116100595780638da5cb5b146100fd578063a69823dc1461012a578063c4d66de81461014a578063f2fde38b1461016a578063f762e7341461018a57600080fd5b80633659cfe61461008b5780634f1ef286146100ad57806352d1902d146100c0578063715018a6146100e8575b600080fd5b34801561009757600080fd5b506100ab6100a6366004610b2e565b6101a8565b005b6100ab6100bb366004610b61565b610290565b3480156100cc57600080fd5b506100d5610360565b6040519081526020015b60405180910390f35b3480156100f457600080fd5b506100ab610413565b34801561010957600080fd5b50610112610449565b6040516001600160a01b0390911681526020016100df565b34801561013657600080fd5b506100ab610145366004610b2e565b6104bc565b34801561015657600080fd5b506100ab610165366004610b2e565b6104fb565b34801561017657600080fd5b506100ab610185366004610b2e565b610615565b34801561019657600080fd5b5060c9546001600160a01b0316610112565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036101f95760405162461bcd60e51b81526004016101f090610c25565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610242600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146102685760405162461bcd60e51b81526004016101f090610c71565b6102718161064a565b6040805160008082526020820190925261028d91839190610652565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036102d85760405162461bcd60e51b81526004016101f090610c25565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610321600080516020610db2833981519152546001600160a01b031690565b6001600160a01b0316146103475760405162461bcd60e51b81526004016101f090610c71565b6103508261064a565b61035c82826001610652565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104005760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016101f0565b50600080516020610db283398151915290565b61041b6107c2565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b60448201526064016101f0565b60c95460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015610493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190610cbd565b905090565b6104c46107c2565b6040516001600160a01b038216907f36c1488d5243eeaf5fb0cf28a35c54973316358b76e9c32ccbe2c57956b0879b90600090a250565b600054610100900460ff161580801561051b5750600054600160ff909116105b806105355750303b158015610535575060005460ff166001145b6105985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016101f0565b6000805460ff1916600117905580156105bb576000805461ff0019166101001790555b6105c482610823565b6105cc610853565b801561035c576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61061d6107c2565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b60448201526064016101f0565b61028d6107c2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561068a576106858361087a565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e4575060408051601f3d908101601f191682019092526106e191810190610cda565b60015b6107475760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016101f0565b600080516020610db283398151915281146107b65760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016101f0565b50610685838383610916565b336107cb610449565b6001600160a01b0316146108215760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101f0565b565b600054610100900460ff1661084a5760405162461bcd60e51b81526004016101f090610cf3565b61028d81610941565b600054610100900460ff166108215760405162461bcd60e51b81526004016101f090610cf3565b6001600160a01b0381163b6108e75760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016101f0565b600080516020610db283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61091f8361098a565b60008251118061092c5750805b156106855761093b83836109ca565b50505050565b600054610100900460ff166109685760405162461bcd60e51b81526004016101f090610cf3565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b6109938161087a565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606109ef8383604051806060016040528060278152602001610dd2602791396109f6565b9392505050565b6060600080856001600160a01b031685604051610a139190610d62565b600060405180830381855af49150503d8060008114610a4e576040519150601f19603f3d011682016040523d82523d6000602084013e610a53565b606091505b5091509150610a6486838387610a6e565b9695505050505050565b60608315610add578251600003610ad6576001600160a01b0385163b610ad65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101f0565b5081610ae7565b610ae78383610aef565b949350505050565b815115610aff5781518083602001fd5b8060405162461bcd60e51b81526004016101f09190610d7e565b6001600160a01b038116811461028d57600080fd5b600060208284031215610b4057600080fd5b81356109ef81610b19565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610b7457600080fd5b8235610b7f81610b19565b9150602083013567ffffffffffffffff80821115610b9c57600080fd5b818501915085601f830112610bb057600080fd5b813581811115610bc257610bc2610b4b565b604051601f8201601f19908116603f01168101908382118183101715610bea57610bea610b4b565b81604052828152886020848701011115610c0357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215610ccf57600080fd5b81516109ef81610b19565b600060208284031215610cec57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b83811015610d59578181015183820152602001610d41565b50506000910152565b60008251610d74818460208701610d3e565b9190910192915050565b6020815260008251806020840152610d9d816040850160208701610d3e565b601f01601f1916919091016040019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122068da0230acd1366802db80aa8fbec2cdf9b29855484e88bbd5526025431b168464736f6c63430008120033", "devdoc": { "author": "Lila Rest (https://lila.rest)", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", @@ -340,7 +340,7 @@ "notice": "Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there." } }, - "notice": "Used to inform subgraph from the existence of a new L-Token contract. Once signaled, a L-Token it will start being indexed.", + "notice": "Used to inform subgraph from the existence of a new L-Token contract. Once signaled, a L-Token will start being indexed.", "version": 1 }, "storageLayout": { @@ -402,15 +402,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7671, + "astId": 7770, "contract": "contracts/src/LTokenSignaler.sol:LTokenSignaler", "label": "_globalOwner", "offset": 0, "slot": "201", - "type": "t_contract(GlobalOwner)4909" + "type": "t_contract(GlobalOwner)4973" }, { - "astId": 7755, + "astId": 7854, "contract": "contracts/src/LTokenSignaler.sol:LTokenSignaler", "label": "__gap", "offset": 0, @@ -441,7 +441,7 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(GlobalOwner)4909": { + "t_contract(GlobalOwner)4973": { "encoding": "inplace", "label": "contract GlobalOwner", "numberOfBytes": "20" diff --git a/contracts/hardhat/deployments/localhost/LTokenSignaler_Proxy.json b/contracts/hardhat/deployments/localhost/LTokenSignaler_Proxy.json index 6ebadf04..74cf15a7 100644 --- a/contracts/hardhat/deployments/localhost/LTokenSignaler_Proxy.json +++ b/contracts/hardhat/deployments/localhost/LTokenSignaler_Proxy.json @@ -79,7 +79,7 @@ "transactionIndex": 0, "gasUsed": "332615", "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000400000000000", - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520", + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927", "transactionHash": "0x0f8861522017b913a03fb6042639ed4b27740c20b210b6a14823edf3ebdccbd4", "logs": [ { @@ -93,7 +93,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520" + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927" }, { "transactionIndex": 0, @@ -105,7 +105,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0x55024eea17b038aae292351432b8264845a3f78090cd51616a4f91b340ba9520" + "blockHash": "0x41438eb689a556c0af29d1c615cabb15982659b8ef0c3ec11f313ab5047be927" } ], "blockNumber": 13, diff --git a/contracts/hardhat/deployments/localhost/LUSDC.json b/contracts/hardhat/deployments/localhost/LUSDC.json index 9e488d67..9093a4fa 100644 --- a/contracts/hardhat/deployments/localhost/LUSDC.json +++ b/contracts/hardhat/deployments/localhost/LUSDC.json @@ -1333,7 +1333,7 @@ "transactionIndex": 0, "gasUsed": "652222", "logsBloom": "0x0000000000000000000000000000000040000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000400000000000000001000000000000000000000000000", - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322", + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132", "transactionHash": "0xec1c869bf0e186536e1800b5313b9282c47faf42885f2c0b8d4c9d6bdf7f67d8", "logs": [ { @@ -1347,7 +1347,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322" + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132" }, { "transactionIndex": 0, @@ -1359,7 +1359,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322" + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132" } ], "blockNumber": 11, diff --git a/contracts/hardhat/deployments/localhost/LUSDC_Implementation.json b/contracts/hardhat/deployments/localhost/LUSDC_Implementation.json index a6c459fb..76c1f3d3 100644 --- a/contracts/hardhat/deployments/localhost/LUSDC_Implementation.json +++ b/contracts/hardhat/deployments/localhost/LUSDC_Implementation.json @@ -1301,41 +1301,41 @@ "type": "function" } ], - "transactionHash": "0xf449fb540d993b15ef859b649eee19c30dcabb598260bae54f50a84b40251dfd", + "transactionHash": "0x71aa7b8fb12b1dc54da294650d3421aa12f0e4cd1b9a8a386f88f2c74f2db3e8", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "contractAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", "transactionIndex": 0, - "gasUsed": "5350885", + "gasUsed": "5364287", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000002000000000000000000000008400000000000000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4307f4b53c14f2a7019b153ec55d718c392a43e08dddae56592bcf19f52d9cc7", - "transactionHash": "0xf449fb540d993b15ef859b649eee19c30dcabb598260bae54f50a84b40251dfd", + "blockHash": "0x8e3479dc62b554c612a64ab167d05f222239d4205e480370f46394c79ad967b1", + "transactionHash": "0x71aa7b8fb12b1dc54da294650d3421aa12f0e4cd1b9a8a386f88f2c74f2db3e8", "logs": [ { "transactionIndex": 0, "blockNumber": 10, - "transactionHash": "0xf449fb540d993b15ef859b649eee19c30dcabb598260bae54f50a84b40251dfd", + "transactionHash": "0x71aa7b8fb12b1dc54da294650d3421aa12f0e4cd1b9a8a386f88f2c74f2db3e8", "address": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", "logIndex": 0, - "blockHash": "0x4307f4b53c14f2a7019b153ec55d718c392a43e08dddae56592bcf19f52d9cc7" + "blockHash": "0x8e3479dc62b554c612a64ab167d05f222239d4205e480370f46394c79ad967b1" } ], "blockNumber": 10, - "cumulativeGasUsed": "5350885", + "cumulativeGasUsed": "5364287", "status": 1, "byzantium": true }, "args": [], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"newAPRUD7x3\",\"type\":\"uint16\"}],\"name\":\"APRChangeEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"id\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum LToken.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountAfterFees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"enum LToken.Status\",\"name\":\"newStatus\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"newId\",\"type\":\"int256\"}],\"name\":\"ActivityEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balanceBefore\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"MintedRewardsEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTVL\",\"type\":\"uint256\"}],\"name\":\"TVLChangeEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"cancelWithdrawalRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositFor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feesRateUD7x3\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"frozenRequests\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fund\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAPR\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedRetained\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"getWithdrawnAmountAndFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"withdrawnAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalBlacklist\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalPause\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"globalPause_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"globalBlacklist_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ldyStaking_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"instantWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"invested\",\"outputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ldyStaking\",\"outputs\":[{\"internalType\":\"contract LDYStaking\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"listenerContract\",\"type\":\"address\"}],\"name\":\"listenToTransfers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"processBigQueuedRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"processQueuedRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"realBalanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"realTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverUnderlying\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"repatriate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"requestWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"retentionRateUD7x3\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardsRedirectsFromTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewardsRedirectsToFrom\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"aprUD7x3\",\"type\":\"uint16\"}],\"name\":\"setAPR\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"feesRateUD7x3_\",\"type\":\"uint32\"}],\"name\":\"setFeesRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"fund_\",\"type\":\"address\"}],\"name\":\"setFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ldyStakingAddress\",\"type\":\"address\"}],\"name\":\"setLDYStaking\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"retentionRateUD7x3_\",\"type\":\"uint32\"}],\"name\":\"setRetentionRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawer_\",\"type\":\"address\"}],\"name\":\"setWithdrawer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"startRewardsRedirection\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"stopRewardsRedirection\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalQueued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transfersListeners\",\"outputs\":[{\"internalType\":\"contract ITransfersListener\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unclaimedFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"underlying\",\"outputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"listenerContract\",\"type\":\"address\"}],\"name\":\"unlistenToTransfers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unmintedRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usableUnderlyings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalQueue\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawalQueueCursor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawer\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:oz-upgrades-unsafe-allow\":\"external-library-linking\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Definitions: - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio). - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees). - Instant: Processed immediately. - Requested: Queued for later processing. - Big Requested: A requested withdrawal exceeding half of the retention rate. - (Withdrawal) queue: An list of all requested withdrawals sorted by priority. - Request ID: The index of a withdrawal request in the queue array. - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain. - Fees Rate: Percentage of fees applied to successful withdrawals. - Usable underlyings: Amount of underlying tokens that have been deposited through expected ways and are so considered as safe to use by the contract. - Transfers listeners: External contracts listening on L-Tokens transfers. - Fund wallet: Wallet managed by the Ledgity's financial team. - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request processing. Note that words between parenthesis are sometimes omitted for brevity.Security: This contract can safely receive funds immediately after initialization. (i.e., there is no way for funds to be sent to non-owned addresses). It is however recommended to replace ASAP owner and fund wallets by multi-sig wallets.For further details, see \\\"LToken\\\" section of whitepaper.\",\"events\":{\"APRChangeEvent(uint16)\":{\"params\":{\"newAPRUD7x3\":\"The new APR in UD7x3 format.\"}},\"ActivityEvent(int256,address,uint8,uint256,uint256,uint8,int256)\":{\"params\":{\"account\":\"The account involved in the activity.\",\"action\":\"The type of activity.\",\"amount\":\"The amount of underlying tokens involved in the activity.\",\"id\":\"ID of the involved withdrawal request or NO_ID (-1) if not applicable.\",\"newId\":\"The new ID of the request if it has been moved in the queue.\",\"newStatus\":\"The new status of the activity.\"}},\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"MintedRewardsEvent(address,uint256,uint256)\":{\"params\":{\"account\":\"The account that received the rewards.\",\"balanceBefore\":\"The balance of the account before the minting.\",\"rewards\":\"The amount of minted rewards.\"}},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"TVLChangeEvent(uint256)\":{\"details\":\"TVL = realTotalSupply()\",\"params\":{\"newTVL\":\"The new TVL of the contract.\"}},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have not been yet minted to the specified account.\",\"params\":{\"account\":\"The account to check the total balance of.\"},\"returns\":{\"_0\":\"The total balance of the account.\"}},\"cancelWithdrawalRequest(uint256)\":{\"params\":{\"requestId\":\"The ID of the withdrawal request to cancel.\"}},\"decimals()\":{\"details\":\"The ERC20WrapperUpgradeable version is preferred because it mirrors the decimals amount of the underlying stablecoin token.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"deposit(uint256)\":{\"params\":{\"amount\":\"The amount of underlying tokens to deposit.\"}},\"depositFor(address,uint256)\":{\"details\":\"Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\"},\"getAPR()\":{\"returns\":{\"_0\":\"The current APR in UD7x3 format.\"}},\"getExpectedRetained()\":{\"returns\":{\"amount\":\"The expected amount of retained underlying tokens.\"}},\"getWithdrawnAmountAndFees(address,uint256)\":{\"params\":{\"account\":\"The account initiating the withdrawal.\",\"amount\":\"The amount of the withdrawal.\"}},\"globalBlacklist()\":{\"returns\":{\"_0\":\"The address of the GlobalBlacklist contract.\"}},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"globalPause()\":{\"returns\":{\"_0\":\"The address of the GlobalPause contract.\"}},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(address,address,address,address,address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalBlacklist_\":\"The address of the GlobalBlacklist contract.\",\"globalOwner_\":\"The address of the GlobalOwner contract.\",\"globalPause_\":\"The address of the GlobalPause contract.\",\"underlyingToken\":\"The address of the underlying stablecoin ERC20 token.\"}},\"instantWithdrawal(uint256)\":{\"details\":\"In order to save some gas and time to users, frontends should propose this function to users only when it has been verified that it will not revert. They should propose the requestWithdrawal() function otherwise.\",\"params\":{\"amount\":\"The amount L-Tokens to withdraw.\"}},\"invested()\":{\"returns\":{\"_0\":\"The reference to the invested token contract.\"}},\"listenToTransfers(address)\":{\"details\":\"Each time a transfer occurs, the onLTokenTransfer() function of the specified contract will be called.IMPORTANT SECURITY NOTE: This method is not intended to be used with contracts that are not owned by the Ledgity team.\",\"params\":{\"listenerContract\":\"The address of the new transfers listener contract.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"paused()\":{\"details\":\"Both version are the same as ERC20BaseUpgradeable.paused() mirrors GlobalPausableUpgradeable.paused(), so a random one is chosen.\",\"returns\":{\"_0\":\"Whether the contract is paused or not.\"}},\"processBigQueuedRequest(uint256)\":{\"details\":\"In contrast to non-big requests processing, this function will uses to fund wallet's balance to fill the request. This allows processing requests that are greater than retention rate without having to exceed this rate on the contract.\",\"params\":{\"requestId\":\"The ID of the big request to process.\"}},\"processQueuedRequests()\":{\"details\":\"For further details, see \\\"LToken > Withdrawals\\\" section of whitepaper.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"realBalanceOf(address)\":{\"params\":{\"account\":\"The account to check the real balance of.\"},\"returns\":{\"_0\":\"The real balance of the account.\"}},\"realTotalSupply()\":{\"returns\":{\"_0\":\"The real total supply of L-Tokens.\"}},\"recoverERC20(address,uint256)\":{\"details\":\"This override of RecoverableUpgradeable.recoverERC20() prevents the recovered token from being the underlying token.\",\"params\":{\"amount\":\"The amount of token to recover.\",\"tokenAddress\":\"The address of the token to recover.\"}},\"recoverUnderlying()\":{\"details\":\"To prevent owner from being able to drain the contract, this function only allows recovering \\\"unusable\\\" underlying tokens, i.e., tokens that have not been sent through fund() or deposit() functions.\"},\"repatriate(uint256)\":{\"details\":\"The function will revert if repatriated amount makes the contract exceeding the retention rate.\",\"params\":{\"amount\":\"The amount of underlying tokens to repatriate.\"}},\"requestWithdrawal(uint256)\":{\"details\":\"The sender must attach 0.003 ETH to pre-pay the future processing gas fees paid by the withdrawer wallet.\",\"params\":{\"amount\":\"The amount L-Tokens to withdraw.\"}},\"setAPR(uint16)\":{\"params\":{\"aprUD7x3\":\"The new APR in UD7x3 format.\"}},\"setFeesRate(uint32)\":{\"params\":{\"feesRateUD7x3_\":\"The new withdrawal fee rate in UD7x3 format.\"}},\"setFund(address)\":{\"params\":{\"fund_\":\"The address of the new fund wallet.\"}},\"setLDYStaking(address)\":{\"params\":{\"ldyStakingAddress\":\"The address of the new LDYStaking contract.\"}},\"setRetentionRate(uint32)\":{\"details\":\"The retention rate is capped at 10%, which ensures that no more than 10% of deposited assets will ever be exposed in this contract (reduces attack surface).\",\"params\":{\"retentionRateUD7x3_\":\"The new retention rate in UD7x3 format.\"}},\"setWithdrawer(address)\":{\"params\":{\"withdrawer_\":\"The address of the new withdrawer wallet.\"}},\"startRewardsRedirection(address,address)\":{\"params\":{\"from\":\"The address of the account to redirect rewards from.\",\"to\":\"The address of the account to redirect rewards to.\"}},\"stopRewardsRedirection(address,address)\":{\"params\":{\"from\":\"The address of the account to stop redirecting rewards from.\",\"to\":\"The address of the account to stop redirecting rewards to.\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"returns\":{\"_0\":\"The total supply of L-Tokens.\"}},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"},\"underlying()\":{\"details\":\"Returns the address of the underlying ERC-20 token that is being wrapped.\"},\"unlistenToTransfers(address)\":{\"details\":\"The onLTokenTransfer() function of the specified contract will not be called anymore each time a L-Token transfer occurs.\",\"params\":{\"listenerContract\":\"The address of the listener contract.\"}},\"unmintedRewardsOf(address)\":{\"details\":\"This is a public implementation of InvestUpgradeable_rewardsOf(). In the context of LToken, this function returns the amount of rewards that have not been distributed/minted yet to the specified account.This is particularly useful for off-chain services to display charts and statistics, as seen in the Ledgity Yield's frontend.\",\"params\":{\"account\":\"The account to check the unminted rewards of.\"},\"returns\":{\"_0\":\"The amount of account's unminted rewards.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"withdrawTo(address,uint256)\":{\"details\":\"Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\"}},\"stateVariables\":{\"frozenRequests\":{\"details\":\"If a request emitter as been blacklisted, its request is moved here to prevent it from blocking the queue.\"},\"transfersListeners\":{\"details\":\"onLTokenTransfer() functions of those contracts will be called on each transfer.\"},\"usableUnderlyings\":{\"details\":\"Are usable, only underlying tokens deposit through deposit() or fund() functions.\"}},\"title\":\"LToken\",\"version\":1},\"userdoc\":{\"events\":{\"APRChangeEvent(uint16)\":{\"notice\":\"Emitted to inform listeners about a change in the APR's value.\"},\"ActivityEvent(int256,address,uint8,uint256,uint256,uint8,int256)\":{\"notice\":\"Emitted to inform listerners about an activity related to deposits and withdrawals.\"},\"MintedRewardsEvent(address,uint256,uint256)\":{\"notice\":\"Emitted to inform listeners that some rewards have been minted.\"},\"TVLChangeEvent(uint256)\":{\"notice\":\"Emitted to inform listeners about a change in the contract's TVL.\"}},\"kind\":\"user\",\"methods\":{\"balanceOf(address)\":{\"notice\":\"Retrieves the total balance of L-Tokens that belong to the account.\"},\"cancelWithdrawalRequest(uint256)\":{\"notice\":\"Cancels a given withdrawal request. The request emitter receive back its L-Tokens and no fees will be charged.\"},\"claimFees()\":{\"notice\":\"Used by owner to claim fees generated from successful withdrawals.\"},\"decimals()\":{\"notice\":\"Required override of decimals() which is implemented by both ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\"},\"deposit(uint256)\":{\"notice\":\"Allows exchanging some underlying tokens for the same amount of L-Tokens.\"},\"depositFor(address,uint256)\":{\"notice\":\"Override of ERC20WrapperUpgradeable.depositFor() that reverts. Use deposit() function instead.\"},\"feesRateUD7x3()\":{\"notice\":\"Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\"},\"frozenRequests(uint256)\":{\"notice\":\"Holds a list of all currently frozen withdrawal requests.\"},\"fund()\":{\"notice\":\"Holds address of fund wallet (managed by Ledgity financial team).\"},\"getAPR()\":{\"notice\":\"Retrieves the most recently set APR.\"},\"getExpectedRetained()\":{\"notice\":\"Computes the maximum amount of underlying tokens that should be retained by the contract (based on retention rate).\"},\"getWithdrawnAmountAndFees(address,uint256)\":{\"notice\":\"Computes fees and net withdrawn amount for a given account withdrawing a given amount.\"},\"globalBlacklist()\":{\"notice\":\"Retrieves the address of GlobalBlacklist contract.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"globalPause()\":{\"notice\":\"Retrieves the address of GlobalPause contract.\"},\"initialize(address,address,address,address,address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"instantWithdrawal(uint256)\":{\"notice\":\"Allows instaneously exchanging a given amount of L-Tokens for the same amount of underlying tokens. It will fail if the contract currently doesn't hold enough underlying tokens to cover the withdrawal.\"},\"invested()\":{\"notice\":\"Retrieves the reference to the invested token contract.\"},\"ldyStaking()\":{\"notice\":\"Holds a reference to the LDYStaking contract.\"},\"listenToTransfers(address)\":{\"notice\":\"Adds a new contract to the L-Token transfers list.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"paused()\":{\"notice\":\"Required override of paused() which is implemented by both GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\"},\"processBigQueuedRequest(uint256)\":{\"notice\":\"Processes a given queued big withdrawal request (one that exceeds half of the retention rate).\"},\"processQueuedRequests()\":{\"notice\":\"Processes queued withdrawal requests until there is else no more requests, else not enough underlying tokens to continue.\"},\"realBalanceOf(address)\":{\"notice\":\"Retrieves the \\\"real\\\" balance of an account, i.e., excluding its not yet minted/distributed rewards.\"},\"realTotalSupply()\":{\"notice\":\"Returns the \\\"real\\\" amount of existing L-Tokens, i.e., excluding not yet minted withdrawal fees and L-Tokens currently in the withdrawal queue.\"},\"recoverERC20(address,uint256)\":{\"notice\":\"Recovers a specified amount of a given token address.\"},\"recoverUnderlying()\":{\"notice\":\"Recovers underlying tokens accidentally sent to the contract.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"repatriate(uint256)\":{\"notice\":\"Used by the fund wallet to repatriate underlying tokens on the contract whenever those are required to fulfill some withdrawal requests.\"},\"requestWithdrawal(uint256)\":{\"notice\":\"Allows requesting the exchange of a given amount of L-Tokens for the same amount of underlying tokens. The request will be automatically processed later.\"},\"retentionRateUD7x3()\":{\"notice\":\"Holds the retention rate in UD7x3 format.\"},\"rewardsRedirectsFromTo(address)\":{\"notice\":\"Holds active rewards redirections in both from->to and to->from[] ways.\"},\"setAPR(uint16)\":{\"notice\":\"Updates the investment APR. Restricted to owner.\"},\"setFeesRate(uint32)\":{\"notice\":\"Updates the current withdrawal fee rate.\"},\"setFund(address)\":{\"notice\":\"Updates the address of the fund wallet.\"},\"setLDYStaking(address)\":{\"notice\":\"Updates the address of LDYStaking contract.\"},\"setRetentionRate(uint32)\":{\"notice\":\"Updates the current underlying token retention rate.\"},\"setWithdrawer(address)\":{\"notice\":\"Updates the address of the withdrawer wallet.\"},\"startRewardsRedirection(address,address)\":{\"notice\":\"Enables redirection of rewards from one account to another.\"},\"stopRewardsRedirection(address,address)\":{\"notice\":\"Disable an active rewards redirection.\"},\"totalQueued()\":{\"notice\":\"Holds the amount of L-Tokens currently in the withdrawal queue.\"},\"totalSupply()\":{\"notice\":\"Retrives the total supply of L-Tokens, including not yet minted withdrawal fees and L-Tokens currently in the withdrawal queue.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transfersListeners(uint256)\":{\"notice\":\"Holds a list of contracts' references that are listening to L-Tokens transfers.\"},\"unclaimedFees()\":{\"notice\":\"Holds the amount of withdrawal fees not yet claimed by contract's owner.\"},\"unlistenToTransfers(address)\":{\"notice\":\"Removes a contract from the L-Token transfers list.\"},\"unmintedRewardsOf(address)\":{\"notice\":\"Retrieves the amount of given account's not yet minted rewards.\"},\"usableUnderlyings()\":{\"notice\":\"Holds the amount of underlying tokens considered as usable by the contract.\"},\"withdrawTo(address,uint256)\":{\"notice\":\"Override of ERC20WrapperUpgradeable.withdrawTo() that reverts. Use instantWithdrawal() or requestWithdrawal() functions instead.\"},\"withdrawalQueue(uint256)\":{\"notice\":\"Holds an ordered list of active withdrawal requests.\"},\"withdrawalQueueCursor()\":{\"notice\":\"Holds the index of the next withdrawal request to process in the queue.\"},\"withdrawer()\":{\"notice\":\"Holds address of withdrawer wallet (managed by withdrawal server).\"}},\"notice\":\"Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e, investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin. As soon as a wallet holds some L-Tokens, it starts receiving rewards in the form of additional L-Tokens, which are auto-compounded over time.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/LToken.sol\":\"LToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0xd14a627157b9a411d2410713e5dd3a377e9064bd5c194a90748bbf27ea625784\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../security/PausableUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract unpausable.\\n */\\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\\n function __ERC20Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xf0bd7f71ffae5f0addd375e8511fbf2ad8ca0c9b2606c32d92bdda7d76a7a81c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../utils/SafeERC20Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of the ERC20 token contract to support token wrapping.\\n *\\n * Users can deposit and withdraw \\\"underlying tokens\\\" and receive a matching number of \\\"wrapped tokens\\\". This is useful\\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\\n * wrapping of an existing \\\"basic\\\" ERC20 into a governance token.\\n *\\n * _Available since v4.2._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\\n IERC20Upgradeable private _underlying;\\n\\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n __ERC20Wrapper_init_unchained(underlyingToken);\\n }\\n\\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n require(underlyingToken != this, \\\"ERC20Wrapper: cannot self wrap\\\");\\n _underlying = underlyingToken;\\n }\\n\\n /**\\n * @dev See {ERC20-decimals}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\\n return value;\\n } catch {\\n return super.decimals();\\n }\\n }\\n\\n /**\\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\\n */\\n function underlying() public view returns (IERC20Upgradeable) {\\n return _underlying;\\n }\\n\\n /**\\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\\n */\\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\\n address sender = _msgSender();\\n require(sender != address(this), \\\"ERC20Wrapper: wrapper can't deposit\\\");\\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\\n _mint(account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\\n */\\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\\n _burn(_msgSender(), amount);\\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\\n * function that can be exposed with access control if desired.\\n */\\n function _recover(address account) internal virtual returns (uint256) {\\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\\n _mint(account, value);\\n return value;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x14bb62a60fcbc911c33ac0e5456bf31ed50b502c30be46ee15bd3b698e91bd81\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x23b997be73d3dd46885262704f0f8cfc7273fdadfe303d37969a9561373972b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Replacement to the LDYStaking contract until the $LDY token is available and\\n * the real LDYStaking can be deployed.\\n *\\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\\n * one the LToken contract relies on.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LDYStaking is Ownable2Step {\\n /**\\n * @notice Holds a mapping of addresses that default to the highest staking tier.\\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\\n */\\n mapping(address => bool) public highTierAccounts;\\n\\n /**\\n * @notice Update high tier status of a given account.\\n * @param account The account to update the high tier status of.\\n */\\n function setHighTierAccount(address account, bool status) external onlyOwner {\\n highTierAccounts[account] = status;\\n }\\n\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * ellgible to any LDY staking tier, except if the account is in the\\n * defaultToHighestTier mapping.\\n * @param account The account to check the tier of.\\n */\\n function tierOf(address account) public view returns (uint256 tier) {\\n if (highTierAccounts[account]) return 3;\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x5d1fd1821e7d5d6cac7424373eb5cbfeebe6a075f897c7f62fb30241ea5b6309\",\"license\":\"MIT\"},\"contracts/src/GlobalBlacklist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalBlacklist\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global mapping of blacklisted accounts on-chain. All contracts\\n * within the Ledgity Yield codebase reference this mapping to prevent access by\\n * blacklisted accounts.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\\n * and getter functions to easily check against this global blacklist.\\n *\\n * @dev For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Mapping of accounts to their blacklist status.\\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\\n */\\n mapping(address => bool) private _list;\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Adds a given account to the blacklist.\\n * @param account The account's address to be blacklisted.\\n */\\n function blacklist(address account) external onlyOwner {\\n require(account != address(0), \\\"L20\\\");\\n _list[account] = true;\\n }\\n\\n /**\\n * @notice Removes a given account from the blacklist.\\n * @param account The account's address to be un-blacklisted.\\n */\\n function unBlacklist(address account) external onlyOwner {\\n _list[account] = false;\\n }\\n\\n /**\\n * @notice Checks whether a given account is blacklisted.\\n * @param account Address of the account to check.\\n * @return 'true' if the account is blacklisted, 'false' otherwise\\n */\\n function isBlacklisted(address account) external view returns (bool) {\\n // Gas optimization: Avoid accessing storage if account is the zero address\\n // (e.g, during a mint or a burn of tokens)\\n if (account == address(0)) return false;\\n\\n // Else, return current account's blacklist status\\n return _list[account];\\n }\\n}\\n\",\"keccak256\":\"0x8e4d4072f74f9d683bf0b54d76fa08201cf507eb791d217178a0ee9d6aaa3ddf\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"},\"contracts/src/GlobalPause.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalPause\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global pause state shared by all contracts of the Ledgity Yield\\n * codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\\n * paused() function that retrieves the pause state from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalPause\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalPause is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n PausableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\\n * but restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n}\\n\",\"keccak256\":\"0x5933aec9779d2d84e00678bf489c8349d8be84fcf479f2a18eb8571a3b900ada\",\"license\":\"MIT\"},\"contracts/src/LToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Contracts\\nimport {ERC20WrapperUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\\\";\\nimport \\\"./abstracts/base/ERC20BaseUpgradeable.sol\\\";\\nimport {InvestUpgradeable} from \\\"./abstracts/InvestUpgradeable.sol\\\";\\nimport {LDYStaking} from \\\"./DummyLDYStaking.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {SUD} from \\\"./libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport {ITransfersListener} from \\\"./interfaces/ITransfersListener.sol\\\";\\n\\n/**\\n * @title LToken\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e,\\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\\n * the form of additional L-Tokens, which are auto-compounded over time.\\n *\\n * @dev Definitions:\\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\\n * - Instant: Processed immediately.\\n * - Requested: Queued for later processing.\\n * - Big Requested: A requested withdrawal exceeding half of the retention rate.\\n * - (Withdrawal) queue: An list of all requested withdrawals sorted by priority.\\n * - Request ID: The index of a withdrawal request in the queue array.\\n * - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain.\\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\\n * expected ways and are so considered as safe to use by the contract.\\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\\n * processing.\\n *\\n * Note that words between parenthesis are sometimes omitted for brevity.\\n *\\n * @dev Security: This contract can safely receive funds immediately after initialization.\\n * (i.e., there is no way for funds to be sent to non-owned addresses). It is however\\n * recommended to replace ASAP owner and fund wallets by multi-sig wallets.\\n *\\n * @dev For further details, see \\\"LToken\\\" section of whitepaper.\\n * @custom:oz-upgrades-unsafe-allow external-library-linking\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /// @dev Represents type of actions triggering ActivityEvent events.\\n enum Action {\\n Deposit,\\n Withdraw\\n }\\n\\n /// @dev Represents different status of actions triggering ActivityEvent events.\\n enum Status {\\n Queued,\\n Cancelled,\\n Success,\\n Moved\\n }\\n\\n /**\\n * @notice Represents a withdrawal request in the queue.\\n * @dev A request fits in a single storage slot (32 bytes).\\n * @param account The account that initiated the request.\\n * @param amount The amount of underlying tokens requested.\\n */\\n struct WithdrawalRequest {\\n address account; // 20 bytes\\n uint96 amount; // 12 bytes\\n }\\n\\n /// @notice Upper limit of retention rate.\\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\\n\\n /// @notice Used in activity events to represent the absence of request ID.\\n int256 private constant NO_ID = -1;\\n\\n /// @notice Holds a reference to the LDYStaking contract.\\n LDYStaking public ldyStaking;\\n\\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\\n address payable public withdrawer;\\n\\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\\n address public fund;\\n\\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\\n uint32 public feesRateUD7x3;\\n\\n /// @notice Holds the retention rate in UD7x3 format.\\n uint32 public retentionRateUD7x3;\\n\\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\\n uint256 public unclaimedFees;\\n\\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\\n uint256 public totalQueued;\\n\\n /**\\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\\n */\\n uint256 public usableUnderlyings;\\n\\n /// @notice Holds an ordered list of active withdrawal requests.\\n WithdrawalRequest[] public withdrawalQueue;\\n\\n /// @notice Holds the index of the next withdrawal request to process in the queue.\\n uint256 public withdrawalQueueCursor;\\n\\n /**\\n * @notice Holds a list of all currently frozen withdrawal requests.\\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\\n * it from blocking the queue.\\n */\\n WithdrawalRequest[] public frozenRequests;\\n\\n /**\\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\\n */\\n ITransfersListener[] public transfersListeners;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the contract's TVL.\\n * @dev TVL = realTotalSupply()\\n * @param newTVL The new TVL of the contract.\\n */\\n event TVLChangeEvent(uint256 newTVL);\\n\\n /**\\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\\n * @param account The account involved in the activity.\\n * @param action The type of activity.\\n * @param amount The amount of underlying tokens involved in the activity.\\n * @param newStatus The new status of the activity.\\n * @param newId The new ID of the request if it has been moved in the queue.\\n */\\n event ActivityEvent(\\n int256 indexed id,\\n address indexed account,\\n Action indexed action,\\n uint256 amount,\\n uint256 amountAfterFees,\\n Status newStatus,\\n int256 newId\\n );\\n\\n /**\\n * @notice Emitted to inform listeners that some rewards have been minted.\\n * @param account The account that received the rewards.\\n * @param balanceBefore The balance of the account before the minting.\\n * @param rewards The amount of minted rewards.\\n */\\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\\n\\n /// @notice Reverts if the function caller is not the withdrawer wallet.\\n modifier onlyWithdrawer() {\\n require(_msgSender() == withdrawer, \\\"L39\\\");\\n _;\\n }\\n\\n /// @notice Reverts if the function caller is not the fund wallet.\\n modifier onlyFund() {\\n require(_msgSender() == fund, \\\"L40\\\");\\n _;\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\\n */\\n function initialize(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address ldyStaking_,\\n address underlyingToken\\n ) public initializer {\\n // Initialize ERC20 base.\\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\\n __ERC20Base_init(\\n globalOwner_,\\n globalPause_,\\n globalBlacklist_,\\n string(abi.encodePacked(\\\"Ledgity \\\", underlyingSymbol)),\\n string(abi.encodePacked(\\\"L\\\", underlyingSymbol))\\n );\\n\\n // IMPORTANT: Below calls must not be restricted to owner at any point.\\n // This is because the GlobalOwner contract may not be a fresh one, and so\\n // the contract deployer may not be the owner anymore after ERC20Base init.\\n\\n // Initialize other parents contracts.\\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\\n __Invest_init_unchained(address(this));\\n\\n // Set LDYStaking contract\\n ldyStaking = LDYStaking(ldyStaking_);\\n\\n // Set initial withdrawal fees rate to 0.3%\\n feesRateUD7x3 = 300;\\n\\n // Set initial retention rate to 10%\\n retentionRateUD7x3 = 10_000;\\n\\n // Default withdrawer and fund wallet to contract owner address. This prevents\\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\\n withdrawer = payable(owner());\\n fund = payable(owner());\\n }\\n\\n /**\\n * @notice Required override of decimals() which is implemented by both\\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\\n * decimals amount of the underlying stablecoin token.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function decimals()\\n public\\n view\\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\\n returns (uint8)\\n {\\n return ERC20WrapperUpgradeable.decimals();\\n }\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @notice Updates the current withdrawal fee rate.\\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\\n */\\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\\n feesRateUD7x3 = feesRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the current underlying token retention rate.\\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\\n * deposited assets will ever be exposed in this contract (reduces attack surface).\\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\\n */\\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \\\"L41\\\");\\n retentionRateUD7x3 = retentionRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the address of LDYStaking contract.\\n * @param ldyStakingAddress The address of the new LDYStaking contract.\\n */\\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\\n ldyStaking = LDYStaking(ldyStakingAddress);\\n }\\n\\n /**\\n * @notice Updates the address of the withdrawer wallet.\\n * @param withdrawer_ The address of the new withdrawer wallet.\\n */\\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\\n // Ensure address is not the zero address (pre-processing fees would be lost else)\\n require(withdrawer_ != address(0), \\\"L63\\\");\\n\\n // Set new withdrawer wallet's address\\n withdrawer = withdrawer_;\\n }\\n\\n /**\\n * @notice Updates the address of the fund wallet.\\n * @param fund_ The address of the new fund wallet.\\n */\\n function setFund(address payable fund_) public onlyOwner {\\n // Ensure address is not the zero address (deposited tokens would be lost else)\\n require(fund_ != address(0), \\\"L64\\\");\\n\\n // Set new fund wallet's address\\n fund = fund_;\\n }\\n\\n /**\\n * @notice Adds a new contract to the L-Token transfers list.\\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\\n * specified contract will be called.\\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\\n * contracts that are not owned by the Ledgity team.\\n * @param listenerContract The address of the new transfers listener contract.\\n */\\n function listenToTransfers(address listenerContract) public onlyOwner {\\n transfersListeners.push(ITransfersListener(listenerContract));\\n }\\n\\n /**\\n * @notice Removes a contract from the L-Token transfers list.\\n * @dev The onLTokenTransfer() function of the specified contract will not be called\\n * anymore each time a L-Token transfer occurs.\\n * @param listenerContract The address of the listener contract.\\n */\\n function unlistenToTransfers(address listenerContract) public onlyOwner {\\n // Find index of listener contract in transferListeners array\\n int256 index = -1;\\n uint256 transfersListenersLength = transfersListeners.length;\\n for (uint256 i = 0; i < transfersListenersLength; i++) {\\n if (address(transfersListeners[i]) == listenerContract) {\\n index = int256(i);\\n break;\\n }\\n }\\n\\n // Revert if given contract wasn't listening to transfers\\n require(index > -1, \\\"L42\\\");\\n\\n // Else, remove transfers listener contract from listeners array\\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\\n transfersListeners.pop();\\n }\\n\\n /**\\n * @notice Retrieves the amount of given account's not yet minted rewards.\\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\\n * context of LToken, this function returns the amount of rewards that have not been\\n * distributed/minted yet to the specified account.\\n * @dev This is particularly useful for off-chain services to display charts and\\n * statistics, as seen in the Ledgity Yield's frontend.\\n * @param account The account to check the unminted rewards of.\\n * @return The amount of account's unminted rewards.\\n */\\n function unmintedRewardsOf(address account) public view returns (uint256) {\\n return _rewardsOf(account, true);\\n }\\n\\n /**\\n * @notice Retrieves the \\\"real\\\" balance of an account, i.e., excluding its not yet\\n * minted/distributed rewards.\\n * @param account The account to check the real balance of.\\n * @return The real balance of the account.\\n */\\n function realBalanceOf(address account) public view returns (uint256) {\\n return super.balanceOf(account);\\n }\\n\\n /**\\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\\n * not been yet minted to the specified account.\\n * @param account The account to check the total balance of.\\n * @return The total balance of the account.\\n */\\n function balanceOf(address account) public view override returns (uint256) {\\n return realBalanceOf(account) + unmintedRewardsOf(account);\\n }\\n\\n /**\\n * @notice Returns the \\\"real\\\" amount of existing L-Tokens, i.e., excluding not yet\\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\\n * @return The real total supply of L-Tokens.\\n */\\n function realTotalSupply() public view returns (uint256) {\\n return super.totalSupply();\\n }\\n\\n /**\\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\\n * fees and L-Tokens currently in the withdrawal queue.\\n * @return The total supply of L-Tokens.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return realTotalSupply() + totalQueued + unclaimedFees;\\n }\\n\\n /**\\n * @notice Recovers a specified amount of a given token address.\\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\\n * token from being the underlying token.\\n * @inheritdoc RecoverableUpgradeable\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\\n // Ensure the token is not the underlying token\\n require(tokenAddress != address(underlying()), \\\"L43\\\");\\n\\n // Proceed to recovery\\n super.recoverERC20(tokenAddress, amount);\\n }\\n\\n /**\\n * @notice Recovers underlying tokens accidentally sent to the contract.\\n * @dev To prevent owner from being able to drain the contract, this function only\\n * allows recovering \\\"unusable\\\" underlying tokens, i.e., tokens that have not been\\n * sent through fund() or deposit() functions.\\n */\\n function recoverUnderlying() external onlyOwner {\\n // Compute the recoverable amount by taking the difference between the contract's\\n // balance and the amount of usable underlying tokens\\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\\n\\n // Revert if there is nothing to recover\\n require(recoverableAmount > 0, \\\"L44\\\");\\n\\n // Else, proceed to underlying tokens recovery\\n super.recoverERC20(address(underlying()), recoverableAmount);\\n }\\n\\n /**\\n * @notice Retrieves the amount of underlying tokens invested by the given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\\n * LToken contract, the investment of an account is equal to its real balance.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _investmentOf(address account) internal view override returns (uint256) {\\n return realBalanceOf(account);\\n }\\n\\n /**\\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract so\\n * it can distribute rewards to accounts before each period reset.\\n * @dev InvestUpgradeable contract already ensure that amount > 0.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\\n // Inform listeners of the rewards minting\\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\\n\\n // Mint L-Tokens rewards to account\\n _mint(account, amount);\\n\\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\\n return true;\\n }\\n\\n /**\\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\\n * called each time an account's balance is going to change.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\\n * @inheritdoc ERC20BaseUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\\n\\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\\n if (from != address(0)) _beforeInvestmentChange(from, true);\\n if (to != address(0)) _beforeInvestmentChange(to, true);\\n }\\n\\n /**\\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\\n * transfers listeners.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already checked in _beforeTokenTransfer().\\n * @inheritdoc ERC20Upgradeable\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n // If some L-Token have been burned/minted, inform listeners of a TVL change\\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\\n\\n // Trigger onLTokenTransfer() functions of all the transfers listeners\\n for (uint256 i = 0; i < transfersListeners.length; i++) {\\n transfersListeners[i].onLTokenTransfer(from, to, amount);\\n }\\n }\\n\\n /**\\n * @notice Computes the maximum amount of underlying tokens that should be retained\\n * by the contract (based on retention rate).\\n * @return amount The expected amount of retained underlying tokens.\\n */\\n function getExpectedRetained() public view returns (uint256 amount) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert totalSupply and retentionRate to SUD\\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\\n\\n // Compute and return expected retained amount\\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(expectedRetainedSUD, d);\\n }\\n\\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\\n function _transferExceedingToFund() internal {\\n // Retrieve the expected amount retained\\n uint256 expectedRetained = getExpectedRetained();\\n\\n // If usable underlyings are less than or equal to expected retained, return\\n if (usableUnderlyings <= expectedRetained) return;\\n\\n // Else, exceeding amount is equal to difference between those values\\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= exceedingAmount;\\n\\n // Transfer the exceeding amount to the fund wallet\\n underlying().safeTransfer(fund, exceedingAmount);\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L45\\\");\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\\n * Use deposit() function instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L46\\\");\\n }\\n\\n /**\\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\\n * @param amount The amount of underlying tokens to deposit.\\n */\\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough underlying tokens to deposit\\n require(underlying().balanceOf(_msgSender()) >= amount, \\\"L47\\\");\\n\\n // Update usable underlyings balance accordingly\\n usableUnderlyings += amount;\\n\\n // Inform listeners of the deposit activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Deposit,\\n amount,\\n amount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\\n super.depositFor(_msgSender(), amount);\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\\n * given amount.\\n * @param account The account initiating the withdrawal.\\n * @param amount The amount of the withdrawal.\\n */\\n function getWithdrawnAmountAndFees(\\n address account,\\n uint256 amount\\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\\n // If the account is eligible to staking tier 2, no fees are applied\\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\\n\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert amount and fees rate to SUD\\n uint256 amountSUD = SUD.fromAmount(amount, d);\\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\\n\\n // Compute fees and withdrawn amount (initial amount minus fees)\\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\\n fees = SUD.toAmount(feesSUD, d);\\n withdrawnAmount = amount - fees;\\n }\\n\\n /**\\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\\n * enough underlying tokens to cover the withdrawal.\\n * @dev In order to save some gas and time to users, frontends should propose this\\n * function to users only when it has been verified that it will not revert. They\\n * should propose the requestWithdrawal() function otherwise.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L48\\\");\\n\\n // Can the contract cover this withdrawal plus all already queued requests?\\n bool cond1 = totalQueued + amount <= usableUnderlyings;\\n\\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\\n\\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\\n if (!(cond1 || cond2)) revert(\\\"L49\\\");\\n\\n // Else, retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\\n\\n // Increase unclaimed fees amount accordingly\\n unclaimedFees += fees;\\n\\n // Decrease usable underlyings balance accordingly\\n usableUnderlyings -= withdrawnAmount;\\n\\n // Inform listeners of this instant withdrawal activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Burn withdrawal fees from the account\\n _burn(_msgSender(), fees);\\n\\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\\n super.withdrawTo(_msgSender(), withdrawnAmount);\\n }\\n\\n /**\\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\\n * amount of underlying tokens. The request will be automatically processed later.\\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\\n * paid by the withdrawer wallet.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function requestWithdrawal(\\n uint256 amount\\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L53\\\");\\n\\n // Ensure the requested amount doesn't overflow uint96\\n require(amount <= type(uint96).max, \\\"L54\\\");\\n\\n // Ensure the sender attached the pre-paid processing gas fees\\n require(msg.value == 0.003 * 10 ** 18, \\\"L55\\\");\\n\\n // Create withdrawal request data\\n WithdrawalRequest memory request = WithdrawalRequest({\\n account: _msgSender(),\\n amount: uint96(amount)\\n });\\n\\n // Will hold the request ID\\n uint256 requestId;\\n\\n // Append request to the withdrawal queue:\\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\\n withdrawalQueueCursor--;\\n requestId = withdrawalQueueCursor;\\n withdrawalQueue[requestId] = request;\\n }\\n // - At the end else\\n else {\\n withdrawalQueue.push(request);\\n requestId = withdrawalQueue.length - 1;\\n }\\n\\n // Increase total amount queued accordingly\\n totalQueued += amount;\\n\\n // Inform listeners of this new queued withdrawal activity event\\n emit ActivityEvent(\\n int256(requestId),\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n amount,\\n Status.Queued,\\n NO_ID\\n );\\n\\n // Burn withdrawal L-Tokens amount from account's balance\\n _burn(_msgSender(), amount);\\n\\n // Forward pre-paid processing gas fees to the withdrawer wallet\\n (bool sent, ) = withdrawer.call{value: msg.value}(\\\"\\\");\\n require(sent, \\\"L56\\\");\\n }\\n\\n /**\\n * @notice Processes queued withdrawal requests until there is else no more requests,\\n * else not enough underlying tokens to continue.\\n * @dev For further details, see \\\"LToken > Withdrawals\\\" section of whitepaper.\\n */\\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\\n // Accumulators variables, will be written on-chain after the loop\\n uint256 cumulatedFees = 0;\\n uint256 cumulatedWithdrawnAmount = 0;\\n uint256 nextRequestId = withdrawalQueueCursor;\\n\\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\\n // requests are increasing the queue length when moved at the end of the queue.\\n uint256 queueLength = withdrawalQueue.length;\\n\\n // Iterate over requests to be processed\\n while (nextRequestId < queueLength) {\\n // Stop processing requests if there is not enough gas left to continue the\\n // loop and properly end the function call. This prevents an attacker from\\n // blocking the withdrawal processing by creating a ton of tiny requests so\\n // this function call cannot fit anymore in block gas limit.\\n if (gasleft() < 45000) break;\\n\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\\n\\n // Skip empty request (processed big requests or cancelled requests)\\n if (request.account == address(0)) {}\\n //\\n // If account has been blacklisted since request emission\\n else if (isBlacklisted(request.account)) {\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request in the frozen requests list\\n frozenRequests.push(request);\\n }\\n //\\n // Or if request is a big request, move it at the end of the queue for now.\\n // This request will be processed manually later using processBigQueuedRequest()\\n else if (request.amount > getExpectedRetained() / 2) {\\n // Inform listeners of this queued request being moved at the end of the queue\\n emit ActivityEvent(\\n int256(nextRequestId),\\n _msgSender(),\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Moved,\\n int256(withdrawalQueue.length)\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request at the end of the queue\\n withdrawalQueue.push(request);\\n }\\n //\\n // Else, continue request processing\\n else {\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Break if the contract doesn't hold enough funds to cover the request\\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\\n\\n // Accumulate fees and withdrawn amount\\n cumulatedFees += fees;\\n cumulatedWithdrawnAmount += withdrawnAmount;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(nextRequestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Transfer underlying tokens to account. Burning L-Tokens is not required\\n // as equestWithdrawal() already did it.\\n // Security note: Re-entrancy warning are disabled as the request has\\n // just been deleted from the queue, it will so be skipped if trying to\\n // process it again.\\n // slither-disable-next-line reentrancy-no-eth\\n underlying().safeTransfer(request.account, withdrawnAmount);\\n }\\n\\n // Increment next request ID\\n nextRequestId++;\\n }\\n\\n // Increase unclaimed fees by the amount of cumulated fees\\n unclaimedFees += cumulatedFees;\\n\\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\\n usableUnderlyings -= cumulatedWithdrawnAmount;\\n\\n // Decrease total amount queued by the cumulated amount requested\\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\\n\\n // Update new queue cursor\\n withdrawalQueueCursor = nextRequestId;\\n\\n // Retention rate cannot exceeds as the withdrawal decreases both usable\\n // underlyings and expected retained amounts by the same number and as the\\n // expected retained amount is a subset of usable underlyings amount.\\n }\\n\\n /**\\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\\n * the retention rate).\\n * @dev In contrast to non-big requests processing, this function will uses to fund\\n * wallet's balance to fill the request. This allows processing requests that are\\n * greater than retention rate without having to exceed this rate on the contract.\\n * @param requestId The ID of the big request to process.\\n */\\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure the request is active\\n require(request.account != address(0), \\\"L66\\\");\\n\\n // Ensure the request emitter has not been blacklisted since request emission\\n require(!isBlacklisted(request.account), \\\"L50\\\");\\n\\n // Ensure this is indeed a big request\\n require(request.amount > getExpectedRetained() / 2, \\\"L51\\\");\\n\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\\n uint256 fundBalance = underlying().balanceOf(fund);\\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \\\"L52\\\");\\n\\n // Increase amount of unclaimed fees accordingly\\n unclaimedFees += fees;\\n\\n // Decrease total queued amount by request amount\\n totalQueued -= request.amount;\\n\\n // Increment queue cursor if request was the next request to be processed\\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[requestId];\\n\\n // If fund wallet's balance can cover request, rely on it only\\n if (withdrawnAmount <= fundBalance) {\\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\\n }\\n // Else, cover request from both fund wallet and contract balances\\n else {\\n // Compute amount missing from fund wallet to cover request\\n uint256 missingAmount = withdrawnAmount - fundBalance;\\n\\n // Decrease usable amount of underlying tokens accordingly\\n usableUnderlyings -= missingAmount;\\n\\n // Transfer entire fund balance to request's emitter\\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\\n\\n // Transfer missing amount from contract balance to request emitter\\n underlying().safeTransfer(request.account, missingAmount);\\n }\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Cancels a given withdrawal request. The request emitter receive back its\\n * L-Tokens and no fees will be charged.\\n * @param requestId The ID of the withdrawal request to cancel.\\n */\\n function cancelWithdrawalRequest(\\n uint256 requestId\\n ) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure request belongs to caller\\n require(_msgSender() == request.account, \\\"L57\\\");\\n\\n // Decrease total amount queued accordingly\\n totalQueued -= request.amount;\\n\\n // Delete the withdrawal request from queue\\n delete withdrawalQueue[requestId];\\n\\n // Inform listeners of this cancelled withdrawal request activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Cancelled,\\n NO_ID\\n );\\n\\n // Mint back L-Tokens to account\\n _mint(request.account, uint256(request.amount));\\n }\\n\\n /**\\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\\n * whenever those are required to fulfill some withdrawal requests.\\n * @dev The function will revert if repatriated amount makes the contract exceeding\\n * the retention rate.\\n * @param amount The amount of underlying tokens to repatriate.\\n */\\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\\n // Ensure the fund wallet has enough funds to repatriate\\n require(amount <= underlying().balanceOf(fund), \\\"L58\\\");\\n\\n // Calculate new contract usable balance\\n uint256 newBalance = usableUnderlyings + amount;\\n\\n // Ensure the new balance doesn't exceed the retention rate\\n require(newBalance <= getExpectedRetained(), \\\"L59\\\");\\n\\n // Increase usable underlyings amount by repatriated amount\\n usableUnderlyings += amount;\\n\\n // Transfer amount from fund wallet to contract\\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\\n }\\n\\n /// @notice Used by owner to claim fees generated from successful withdrawals.\\n function claimFees() external onlyOwner {\\n // Ensure there are some fees to claim\\n require(unclaimedFees > 0, \\\"L60\\\");\\n\\n // Ensure the contract holds enough underlying tokens to cover fees\\n require(usableUnderlyings >= unclaimedFees, \\\"L61\\\");\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= unclaimedFees;\\n\\n // Store fees amount in memory and reset unclaimed fees amount\\n uint256 fees = unclaimedFees;\\n unclaimedFees = 0;\\n\\n // Transfer unclaimed fees to owner\\n underlying().safeTransfer(owner(), fees);\\n }\\n}\\n\",\"keccak256\":\"0x03fb59d6d4523deb913cf263137bb0f6d71c5a790aa2ec3556607fcf53184c8e\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x59c14d38e9e96d4f60cf2fd626c56e23928fce85107ac8d603dfdb90c9d81ec4\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalPausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalPause} from \\\"../GlobalPause.sol\\\";\\n\\n/**\\n * @title GlobalPausableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit pause state from the specified GlobalPause\\n * contract (see GlobalPause.sol). This design facilitates centralized management of\\n * pause state for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalPause state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalPausableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\\n /**\\n * @notice The GlobalPause contract the pause state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalPause private _globalPause;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalPause_ The address of the GlobalPause contract.\\n */\\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n }\\n\\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\\n _globalPause = GlobalPause(globalPause_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalPause contract.\\n * @return The address of the GlobalPause contract.\\n */\\n function globalPause() public view returns (address) {\\n return address(_globalPause);\\n }\\n\\n /**\\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\\n * from the GlobalPause contract instead.\\n * @return Whether the contract is paused or not.\\n */\\n function paused() public view virtual override returns (bool) {\\n return _globalPause.paused();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9ab501a2f6256a59e1712576423d4bc2fb97283aee704b87f1b3a749e85d1178\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalRestrictableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalBlacklist} from \\\"../GlobalBlacklist.sol\\\";\\n\\n/**\\n * @title GlobalRestrictableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit blacklist state from the specified\\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\\n * centralized management of a blacklist for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalBlacklist state must be set at initialization-time and for\\n * evident security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalRestrictableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalRestrictableUpgradeable is Initializable {\\n /**\\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalBlacklist private _globalBlacklist;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n }\\n\\n function __GlobalRestrictable_init_unchained(\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalBlacklist contract.\\n * @return The address of the GlobalBlacklist contract.\\n */\\n function globalBlacklist() public view returns (address) {\\n return address(_globalBlacklist);\\n }\\n\\n /**\\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n */\\n modifier notBlacklisted(address account) {\\n require(isBlacklisted(account) == false, \\\"L9\\\");\\n _;\\n }\\n\\n /**\\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n * @return Whether the account is blacklisted.\\n */\\n function isBlacklisted(address account) internal view returns (bool) {\\n return _globalBlacklist.isBlacklisted(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb2413fea06f7221472d88b7d4f9be6e6a4efd8935e0b6857077667e6c881a9ea\",\"license\":\"MIT\"},\"contracts/src/abstracts/InvestUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Contracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"./GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"./GlobalRestrictableUpgradeable.sol\\\";\\nimport \\\"./base/BaseUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../abstracts/RecoverableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {APRHistory as APRH} from \\\"../libs/APRHistory.sol\\\";\\nimport {SUD} from \\\"../libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title InvestUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with utilities to manage an invested token,\\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\\n *\\n * @dev Intuition:\\n * This contract primarily exists for code splitting and reusability. It unburdens the\\n * LToken contract code, making it easier to understand and maintain.\\n *\\n * This contract is generic because it may be used in the LDYStaking contract in the future.\\n *\\n * @dev Definitions:\\n * - Investment: The act of depositing or investing tokens into the contract.\\n * - Investment period: Time between the start of an investment or the last rewards\\n * distribution for an account to the present.\\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\\n * distributed between investment periods.\\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\\n *\\n * @dev Derived contract must:\\n * - Set invested token during initialization\\n * - Implement _investmentOf() function\\n * - Implement _distributeRewards() function (optional)\\n *\\n * @dev For further details, see \\\"InvestmentUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract InvestUpgradeable is BaseUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using APRH for APRH.Pack[];\\n\\n /**\\n * @notice Represents an account's investment period.\\n * @param timestamp The timestamp of the most recent rewards distribution.\\n * @param ref The reference of the last APR checkpoint at that timestamp.\\n */\\n struct InvestmentPeriod {\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n APRH.Reference ref;\\n }\\n\\n /**\\n * @notice Represents the investment details of an account.\\n * @param period The current investment period of the account.\\n * @param virtualBalance May hold a part of account rewards until they are claimed.\\n */\\n struct AccountDetails {\\n InvestmentPeriod period;\\n uint256 virtualBalance;\\n }\\n\\n /// @notice Holds a reference to the invested token's contract.\\n IERC20Upgradeable private _invested;\\n\\n /// @notice Holds investment details of each account.\\n mapping(address => AccountDetails) internal accountsDetails;\\n\\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\\n APRH.Pack[] private _aprHistory;\\n\\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\\n mapping(address => address) public rewardsRedirectsFromTo;\\n mapping(address => address[]) public rewardsRedirectsToFrom;\\n\\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\\n bool private _isClaiming;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the APR's value.\\n * @param newAPRUD7x3 The new APR in UD7x3 format.\\n */\\n event APRChangeEvent(uint16 newAPRUD7x3);\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param invested_ The address of the invested token contract.\\n */\\n function __Invest_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address invested_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __Invest_init_unchained(invested_);\\n }\\n\\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\\n // Set invested token\\n _invested = IERC20Upgradeable(invested_);\\n\\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\\n // of an empty APR history\\n _aprHistory.setAPR(0);\\n }\\n\\n /**\\n * @notice Retrieves the reference to the invested token contract.\\n * @return The reference to the invested token contract.\\n */\\n function invested() public view returns (IERC20Upgradeable) {\\n return _invested;\\n }\\n\\n /**\\n * @notice Updates the investment APR. Restricted to owner.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(uint16 aprUD7x3) public onlyOwner {\\n _aprHistory.setAPR(aprUD7x3);\\n emit APRChangeEvent(aprUD7x3);\\n }\\n\\n /**\\n * @notice Retrieves the most recently set APR.\\n * @return The current APR in UD7x3 format.\\n */\\n function getAPR() public view returns (uint16) {\\n return _aprHistory.getAPR();\\n }\\n\\n /**\\n * @notice Enables redirection of rewards from one account to another.\\n * @param from The address of the account to redirect rewards from.\\n * @param to The address of the account to redirect rewards to.\\n */\\n function startRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure the address is not already redirecting rewards\\n require(rewardsRedirectsFromTo[from] == address(0), \\\"L62\\\");\\n\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L12\\\");\\n require(to != address(0), \\\"L13\\\");\\n\\n // Ensure 'from' and 'to' addresses are distinct\\n require(from != to, \\\"L14\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L15\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Activate rewards redirection\\n rewardsRedirectsFromTo[from] = to;\\n rewardsRedirectsToFrom[to].push(from);\\n }\\n\\n /**\\n * @notice Disable an active rewards redirection.\\n * @param from The address of the account to stop redirecting rewards from.\\n * @param to The address of the account to stop redirecting rewards to.\\n */\\n function stopRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L16\\\");\\n require(to != address(0), \\\"L17\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L18\\\");\\n\\n // Ensure a rewards redirection was active\\n require(rewardsRedirectsFromTo[from] == to, \\\"L19\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Retrieve 'from' index in the redirection array of 'to'\\n int256 fromIndex = -1;\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\\n if (rewardsRedirectsToFrom[to][i] == from) {\\n fromIndex = int256(i);\\n break;\\n }\\n }\\n\\n // fromIndex should never be -1 at this point\\n assert(fromIndex >= 0);\\n\\n // Deactivate rewards redirection\\n rewardsRedirectsFromTo[from] = address(0);\\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\\n rewardsRedirectsToFrom[to].length - 1\\n ];\\n rewardsRedirectsToFrom[to].pop();\\n }\\n\\n /**\\n * @notice Retrieves the total amount of tokens invested by the given account.\\n * @dev Derived contracts must implement this function.\\n * @param account The account to get the investment of.\\n * @return The total amount of tokens invested by the given account.\\n */\\n function _investmentOf(address account) internal view virtual returns (uint256);\\n\\n /**\\n * @notice Distributes a specified amount of rewards to a given account.\\n * @dev Derived contracts may optionally implement this function.\\n * @dev Implementations must return true to indicate a successful distribution, and\\n * false otherwise. If it returns false, the rewards will be added to the account's\\n * virtual balance, in order to be claimed later.\\n * @param account The account to claim the rewards of.\\n * @param amount The amount of rewards to claim.\\n * @return Whether the rewards distribution was successfull.\\n */\\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\\n account; // Silence unused variables warning\\n amount;\\n return false;\\n }\\n\\n /**\\n * @notice Computes the rewards accrued over a specified period of time, based on a\\n * given APR and amount of invested tokens.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param beginTimestamp The moment the period commenced.\\n * @param endTimestamp The moment the period concluded.\\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\\n * @param investedAmount The amount of tokens deposited/invested during the period.\\n * @return The amount of rewards generated during the period.\\n */\\n function _calculatePeriodRewards(\\n uint40 beginTimestamp,\\n uint40 endTimestamp,\\n uint16 aprUD7x3,\\n uint256 investedAmount\\n ) internal view returns (uint256) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Compute the number of elapsed years\\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\\n\\n // Compute the growth in invested amount (thanks to rewards)\\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\\n\\n // Compute and return the rewards\\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(rewardsSUD, d);\\n }\\n\\n /**\\n * @notice Computes the sum of given account's invested amount, plus invested amount\\n * of all accounts that recursively redirect rewards to this account.\\n * @param account The account to calculate the deep investment of.\\n * @return deepInvestedAmount The deep invested amount.\\n */\\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\\n // Consider account's direct investment\\n deepInvestedAmount += _investmentOf(account);\\n\\n // But also the deep investments of all accounts redirecting rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param account The account to calculate the unclaimed rewards of.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\\n */\\n function _rewardsOf(\\n address account,\\n bool autocompound\\n ) internal view returns (uint256 rewards) {\\n // Retrieve account's investment details\\n AccountDetails memory details = accountsDetails[account];\\n\\n // Retrieve account's deep invested amount\\n uint256 investedAmount = _deepInvestmentOf(account);\\n\\n // Return 0 if the account has never invested or has no invested amount\\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\\n\\n // Retrieve reference and data of APR checkpoint at which started investment period\\n APRH.Reference memory currRef = details.period.ref;\\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\\n\\n // Retrieve reference of latest APR checkpoint\\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\\n\\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\\n // See \\\"InvestUpgradeable > Rewards calculation > 1)\\\" section of the whitepaper\\n rewards = details.virtualBalance;\\n\\n // If start checkpoint is not the latest one\\n if (!APRH.eq(currRef, latestRef)) {\\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // 2) Calculate rewards from investment period start to next checkpoint\\n // See \\\"InvestUpgradeable > Rewards calculation > 2)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n\\n // 3) Calculate rewards for each crossed pair of checkpoints\\n // See \\\"InvestUpgradeable > Rewards calculation > 3)\\\" section of the whitepaper\\n while (true) {\\n // Set next checkpoint as the current one\\n currRef = nextRef;\\n currCheckpoint = nextCheckpoint;\\n\\n // Break if current checkpoint is the latest one\\n if (APRH.eq(currRef, latestRef)) break;\\n\\n // Else, retrieve the new next checkpoint\\n nextRef = APRH.incrementReference(currRef);\\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // Calculate rewards between the current pair of checkpoints\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n\\n // 4) Calculate rewards from the latest checkpoint to now\\n // See \\\"InvestUpgradeable > Rewards calculation > 4)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n } else {\\n // 2.bis) Calculate rewards from investment period start to now\\n // See \\\"InvestUpgradeable > Rewards calculation > 2.bis)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n }\\n\\n /**\\n * @notice Recursively resets the investment period of the specified account and of\\n * all accounts that directly or indirectly redirect rewards to this account.\\n * @param account The account to deeply reset the investment period of.\\n */\\n function _deepResetInvestmentPeriodOf(address account) internal {\\n // Reset account investment period timestamp and APR checkpoint to latest ones\\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\\n\\n // Also reset the ones of all accounts that recursively redirect rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Hook to be invoked before the invested amount of an account changes. It\\n * ensures that rewards are distributed and that account's investment period is reset.\\n * @param account The account whose invested amount is going to change.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n */\\n function _beforeInvestmentChange(address account, bool autocompound) internal {\\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\\n // minted in LToken._distributeRewards(), this guards against infinite loop.\\n if (_isClaiming) return;\\n\\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\\n // As first call will treat both addresses, the second call would be redundant.\\n // Therefore, we skip accounts already processed in this block to save up some gas.\\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\\n\\n // If account redirects its rewards\\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\\n if (redirectRewardsTo != address(0)) {\\n // Call hook on redirection target (this will indirectly reset the investment\\n // of this source account) and return\\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\\n return;\\n }\\n\\n // Else, compute account's undistributed/unclaimed rewards\\n uint256 rewards = _rewardsOf(account, autocompound);\\n\\n // If there are some rewards\\n if (rewards > 0) {\\n // Try to distribute rewards to account\\n _isClaiming = true;\\n bool distributed = _distributeRewards(account, rewards);\\n _isClaiming = false;\\n\\n // If rewards have not been distributed, accumulate them in account's virtual balance\\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\\n }\\n\\n // Finally, deeply reset investment period of the account\\n _deepResetInvestmentPeriodOf(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x62af366fd32223f266d27c26fa74b0ba818ef277a62aa27a00f9000531841079\",\"license\":\"MIT\"},\"contracts/src/abstracts/RecoverableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Conracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @title RecoverableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with helpers functions that allow recovering\\n * assets accidentally sent to them.\\n *\\n * @dev Note: This abstract contract currently supports only ERC20 tokens. Derived\\n * contracts currently do not implement necessary functions to receive Ether or\\n * ERC721/ERC1155 tokens.\\n *\\n * @dev For further details, see \\\"RecoverableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init(globalOwner_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Recoverable_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Recovers a specified amount of a given token address. Will fail if the\\n * contract doesn't hold enough tokens.\\n * @param tokenAddress The address of the token to recover.\\n * @param amount The amount of token to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\\n // Ensure the specified amount is not zero\\n require(amount > 0, \\\"L10\\\");\\n\\n // Create a reference to token's contract\\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\\n\\n // Ensure there is enough token to recover\\n require(tokenContract.balanceOf(address(this)) >= amount, \\\"L11\\\");\\n\\n // Transfer the recovered token amount to the sender\\n tokenContract.safeTransfer(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x00079960b44569f62b9dbccbe7c082b15e13fd769c721fad14c0b2cf36af1a59\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"../GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"../GlobalRestrictableUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../RecoverableUpgradeable.sol\\\";\\n\\n/**\\n * @title BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contract acts as a base for numerous contracts contract in this\\n * codebase, minimizing code repetition and enhancing readability and maintainability.\\n *\\n * @dev For further details, see \\\"Base\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract BaseUpgradeable is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n GlobalPausableUpgradeable,\\n GlobalRestrictableUpgradeable,\\n RecoverableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n __UUPSUpgradeable_init();\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x076f9babfcc47adaa8fbecf462fa1a6f301b0397ddf59c86b6d297608fcf8106\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/ERC20BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\\\";\\nimport {ERC20PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport \\\"./BaseUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\n\\n/**\\n * @title ERC20BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contracts is an extension of BaseUpgradeable intended to be used\\n * as a base for ERC20 tokens contracts.\\n *\\n * @dev For further details, see \\\"ERC20BaseUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract ERC20BaseUpgradeable is\\n ERC20Upgradeable,\\n BaseUpgradeable,\\n ERC20PausableUpgradeable\\n{\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param name_ The display name of the token.\\n * @param symbol_ The symbol of the token.\\n */\\n function __ERC20Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n string memory name_,\\n string memory symbol_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __ERC20_init(name_, symbol_);\\n __ERC20Pausable_init_unchained();\\n }\\n\\n function __ERC20Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\\n * state from the GlobalPause contract.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, PausableUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\\n * The ERC20PausableUpgradeable version is preferred because it also checks that\\n * the contract is not paused before allowing the transfer.\\n * @inheritdoc ERC20PausableUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n )\\n internal\\n virtual\\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\\n whenNotPaused\\n notBlacklisted(from)\\n notBlacklisted(to)\\n {\\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xf7cbb57bea04cbd394d05a4b216e06c84ba82e35e674042d699a813edd6e50da\",\"license\":\"MIT\"},\"contracts/src/interfaces/ITransfersListener.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\ninterface ITransfersListener {\\n function onLTokenTransfer(address from, address to, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0xb71129e8db615bfc1601206027a7056547b997dd2d9aacd9d2aec00508a412c7\",\"license\":\"MIT\"},\"contracts/src/libs/APRHistory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title APRHistory\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This library offers utilities to efficiently maintain on chain, the history of\\n * an APR (Annual Percentage Rate). Each entry in this history is called a \\\"checkpoint\\\".\\n *\\n * @dev Intuition:\\n * Each checkpoint in an APR history consists in two data:\\n * - the creation timestamp\\n * - the APR at that time\\n *\\n * Given that reads and writes to storage slots are among the most costly operations in\\n * Solidity, this library provides a way to store those data on chain in a way that\\n * minimizes the number of used storage slots.\\n *\\n * Instead of storing each checkpoint in a separate storage slot, this library\\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\\n *\\n * @dev Definitions:\\n * - Checkpoint: A record of an APR change\\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\\n * - History: A dynamic array of packs\\n * - Reference: A storage pointer to a checkpoint in the APR history\\n * - CheckpointData: An in-memory representation of a checkpoint data\\n *\\n * @dev Limitation: This library can accommodate APRs only up to 65.536%. This is however\\n * sufficient for APR in LToken contract, which is expected to remain below 10%.\\n *\\n * @dev For further details, see \\\"APRHistory\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary APRHistory {\\n /**\\n * @notice Represents data of a checkpoint extracted from the on-chain history.\\n * For on-chain representation see \\\"Pack\\\" struct.\\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\\n * @param timestamp Timestamp of the checkpoint's creation.\\n */\\n struct CheckpointData {\\n uint16 aprUD7x3; // Allows up to 65.536%\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n }\\n\\n /**\\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\\n * @param aprsUD7x3 Array of checkpoints' APRs.\\n * @param timestamps Array of checkpoints' timestamps.\\n * @param cursor Index of the next checkpoint to be written.\\n */\\n struct Pack {\\n uint16[4] aprsUD7x3;\\n uint40[4] timestamps;\\n uint32 cursor;\\n }\\n\\n /**\\n * @notice Represents a storage pointer to a specific checkpoint in the history.\\n * @param packIndex Index of the pack the checkpoint belongs to.\\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\\n */\\n struct Reference {\\n uint256 packIndex;\\n uint32 cursorIndex;\\n }\\n\\n /**\\n * @notice Compares two checkpoints references.\\n * @param ref1 The first reference to compare.\\n * @param ref2 The second reference to compare.\\n * @return Whether the two references points to the same checkpoint.\\n */\\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\\n }\\n\\n /**\\n * @notice Returns the reference of the checkpoint that should come right after the\\n * referenced checkpoint in the APR history.\\n * @param ref The reference to be incremented.\\n * @return The incremented reference.\\n */\\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L1\\\");\\n\\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\\n //\\n // Else, return ref of next slot in current pack\\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\\n }\\n\\n /**\\n * @notice Extracts checkpoint data from a given reference and in APR history.\\n * @param self The APR history to extract the checkpoint from.\\n * @param ref The reference of the checkpoint data to extract.\\n * @return The extracted checkpoint's data.\\n */\\n function getDataFromReference(\\n Pack[] storage self,\\n Reference memory ref\\n ) public view returns (CheckpointData memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L2\\\");\\n\\n // Ensure pack index of the given ref exists in history\\n require(ref.packIndex < self.length, \\\"L3\\\");\\n\\n // Retrieve pack data from history\\n Pack memory pack = self[ref.packIndex];\\n\\n // Ensure cursor index of the given ref has been written\\n require(ref.cursorIndex < pack.cursor, \\\"L4\\\");\\n\\n // Build and return the checkpoint data\\n return\\n CheckpointData({\\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\\n timestamp: pack.timestamps[ref.cursorIndex]\\n });\\n }\\n\\n /**\\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\\n * @param self The history to extract the reference from.\\n * @return The reference of the latest checkpoint.\\n */\\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\\n // Ensure the given history is not empty\\n require(self.length != 0, \\\"L5\\\");\\n\\n // Retrieve latest pack's index and cursor\\n uint256 packIndex = self.length - 1;\\n uint32 packCursor = self[packIndex].cursor;\\n\\n // If this is the first pack ever, ensure it is not empty\\n if (packIndex == 0) require(packCursor != 0, \\\"L6\\\");\\n\\n // If the pack is empty, return ref of previous pack's latest slot\\n if (packCursor == 0) return Reference(packIndex - 1, 3);\\n //\\n // Else, return ref of previous slot in current pack\\n else return Reference(packIndex, packCursor - 1);\\n }\\n\\n /**\\n * @notice Appends a new empty pack to the end of the given APR history array.\\n * @param self The APR history to append an empty to.\\n */\\n function newBlankPack(Pack[] storage self) internal {\\n // If history is not empty, ensure the latest pack is full\\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \\\"L7\\\");\\n\\n // Push a new blank pack to the history array\\n self.push(\\n Pack({\\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\\n cursor: 0\\n })\\n );\\n }\\n\\n /**\\n * @notice Write a new APR checkpoint at the end of the given history array.\\n * @param self The array of packs to write the new checkpoint to.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\\n // Determine the reference where the new checkpoint should be written\\n Reference memory newRef = self.length == 0\\n ? Reference(0, 0)\\n : incrementReference(getLatestReference(self));\\n\\n // If pack to be written doesn't exist yet, push a new blank pack in history\\n if (newRef.packIndex >= self.length) newBlankPack(self);\\n\\n // Retrieve the pack where the new checkpoint will be stored\\n Pack memory pack = self[newRef.packIndex];\\n\\n // Add new checkpoint's data to the pack\\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\\n\\n // Increment the pack's cursor\\n pack.cursor++;\\n\\n // Write the updated pack in storage\\n self[newRef.packIndex] = pack;\\n }\\n\\n /**\\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\\n * @param self The history array to read APR from.\\n * @return The latest checkpoint's APR.\\n */\\n function getAPR(Pack[] storage self) public view returns (uint16) {\\n // Retrieve the latest checkpoint data\\n Reference memory ref = getLatestReference(self);\\n CheckpointData memory data = getDataFromReference(self, ref);\\n\\n // Return the latest checkpoint's APR\\n return data.aprUD7x3;\\n }\\n}\\n\",\"keccak256\":\"0x7954e7130fb127fc8cd81fb852de2df2eda688c0d4ef6cdd9280809cdf2815c3\",\"license\":\"MIT\"},\"contracts/src/libs/SUD.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title SUD\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice SUD serves as an intermediary number format for calculations within this\\n * codebase. It ensures consistency and reduces precision losses. This library\\n * facilitates conversions between various number formats and the SUD format.\\n *\\n * @dev Intuition:\\n * This codebase employs UD (unsigned decimal fixed-point numbers) format to represent\\n * both percentage rates and tokens amounts.\\n *\\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\\n * the decimals() value of the involved tokens.\\n *\\n * Three challenges arise from this:\\n * 1) To compute values together, it's essential that they are in the same format\\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\\n * precision loss (because division shrinks). A common approach is to scale up and\\n * down values by a few decimals before and after performing calculations.\\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\\n * be shrinked in case token's decimals number is in [0, 2].\\n *\\n * To address these challenges, this library provides the SUD format, which acts as a\\n * consistent and scaled intermediate format to perform calculations on.\\n *\\n * SUD is an acronym for either \\\"Scaled UD\\\" or \\\"Safe UD\\\".\\n *\\n * @dev Definitions:\\n * - Integer: A number without fractional part, e.g., block.timestamp\\n * - UD: A decimal unsigned fixed-point number. The \\\"UD\\\" notation is inspired from\\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\\n * - Amount: An UD with an unknown (at writing time) repartition of digits between\\n * integral and fractional parts. Represents a token amount.\\n * - Rate: An UD with 7 integral digits and 3 fractional ones (a.k.a UD7x3).\\n * Represents a percentage rate.\\n * - SUD: An UD with 3 more decimals than the involved rate or amount with the highest\\n * decimals number. As rates are represented by UD7x3, a SUD number has at least 6\\n * decimals (3+3) and so ranges from UD71x6 to UD0x77 formats.\\n * Used as an intermediate format to perform calculations.\\n *\\n * @dev This library provides utilities to perform the following conversions:\\n * - Amount <--> SUD\\n * - Rate (UD7x3) <--> SUD\\n * - Integer <--> SUD\\n *\\n * @dev Why scaling by 3 decimals?\\n * - It provides an adequate degree of precision for this codebase,\\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\\n * the involved token's decimal number.\\n *\\n * @dev Optimization note: The functions of this library are not set to external because\\n * incorporating them directly into contracts is more gas-efficient. Given their minimal\\n * size and frequent usage in the InvestUpgradeable, LDYStaking, and LToken contracts,\\n * any bytecode savings from making them external are negated by the additional bytecode\\n * required for external calls to this library.\\n * The can be observed by comparing the output of `pnpm cc:size` when those functions's\\n * visibility is set to external or internal.\\n *\\n * @dev Precision note: While this library mitigates precision loss during calculations\\n * on UD numbers, it's important to note that tokens with lower decimal counts and supply\\n * inherently suffer more from precision loss. Conversely, tokens with higher decimal\\n * counts and supply will experience less precision loss.\\n *\\n * @dev For further details, see \\\"SUD\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary SUD {\\n /**\\n * @notice Retrieves decimals number of the given ERC20 contract address.\\n * @param tokenAddress The address to retrieve decimals number from.\\n * @return decimals The decimals number of the given ERC20 contract address.\\n */\\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\\n }\\n\\n /**\\n * @notice Convert a given token amount into SUD format.\\n * @param nAmount The token amount to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The amount in SUD format\\n */\\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\\n\\n // Else return a number with decimals+3 fractional digits\\n return nAmount * 10 ** 3;\\n }\\n\\n /**\\n * @notice Convert a given SUD number into token amount format.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nAmount The number in amount format\\n */\\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** 3;\\n }\\n\\n /**\\n * @notice Converts a given UD7x3 rate into SUD format.\\n * @param nUD7x3 The UD7x3 rate to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The rate in SUD format.\\n */\\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nUD7x3 * 10 ** 3;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return nUD7x3 * 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given SUD number into a UD7x3 rate.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nUD7x3 The number in UD7x3 rate format.\\n */\\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 3;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given integer into SUD format.\\n * @param n The integer to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The integer in SUD format.\\n */\\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return n * 10 ** 6;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return n * 10 ** (decimals + 3);\\n }\\n\\n /**\\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return n The SUD number as an integer.\\n */\\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 6;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** (decimals + 3);\\n }\\n}\\n\",\"keccak256\":\"0x70c9f9f0ae1875fae1ae6c06a3cd73d405f5a6e2b74493690c044d86acf21f79\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615f536200011f60003960008181611462015281816114a2015281816118fd0152818161193d01526119d00152615f536000f3fe6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b6040516104009190615460565b60405180910390f35b34801561041557600080fd5b506104296104243660046154a8565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b506104596104543660046154d4565b610cd5565b005b34801561046757600080fd5b506104596104763660046154d4565b610d41565b34801561048757600080fd5b506104596104963660046154f1565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f03660046154a8565b611037565b34801561050157600080fd5b50610429610510366004615562565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b506104296105453660046154a8565b61141d565b34801561055657600080fd5b5061055f61144e565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c3660046154d4565b611458565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e53660046154a8565b611537565b3480156105f657600080fd5b506105b26106053660046154a8565b611559565b34801561061657600080fd5b506104596106253660046155a3565b611592565b34801561063657600080fd5b506104596106453660046155a3565b611786565b610459610658366004615654565b6118f3565b34801561066957600080fd5b506104b06119c3565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a43660046155a3565b611a76565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611ab2565b3480156106f157600080fd5b506104596107003660046154d4565b611abc565b34801561071157600080fd5b506104596107203660046156f7565b611c13565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f3660046154d4565b611cc4565b34801561077057600080fd5b50610459611ce2565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c23660046155a3565b611d18565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b506104596108013660046155a3565b6120d4565b34801561081257600080fd5b506104596108213660046154a8565b612258565b34801561083257600080fd5b506105b26108413660046154d4565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b26122bd565b34801561087e57600080fd5b5061045961088d366004615714565b61232c565b34801561089e57600080fd5b506103f3612563565b3480156108b357600080fd5b506104b06108c23660046154d4565b612572565b3480156108d357600080fd5b506104596108e23660046154d4565b612590565b6104596108f53660046155a3565b6125eb565b34801561090657600080fd5b506104296109153660046154a8565b612952565b34801561092657600080fd5b506104596109353660046154d4565b6129d8565b34801561094657600080fd5b50610459610955366004615714565b612a03565b34801561096657600080fd5b506104296109753660046154a8565b612d39565b34801561098657600080fd5b50610459612d47565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb3660046155a3565b612e30565b3480156109dc57600080fd5b506109f06109eb3660046154a8565b612f87565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a203660046155a3565b6130a3565b348015610a3157600080fd5b50610a3a6130b4565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae23660046154d4565b61312c565b348015610af357600080fd5b50610459613139565b348015610b0857600080fd5b506104b06131fa565b348015610b1d57600080fd5b506104b0610b2c366004615714565b613281565b348015610b3d57600080fd5b50610459610b4c36600461575f565b6132ac565b348015610b5d57600080fd5b506105b2610b6c3660046155a3565b6132db565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b0613306565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be53660046154d4565b613311565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461575f565b613346565b6060609a8054610c389061577c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c649061577c565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc98185856133b3565b60019150505b92915050565b610cdd6134d7565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d496134d7565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed091908101906157b0565b9050610f1d87878784604051602001610ee99190615827565b60405160208183030381529060405285604051602001610f099190615857565b604051602081830303815290604052613538565b610f268361357c565b610f2f306135ac565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f736122bd565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c6122bd565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e613306565b6110289190615896565b6110329190615896565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613656565b6110818585856136d0565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e061388c565b610300546102ff5460009182915b808210156113c05761afc85a106113c05760006102ff8381548110611115576111156158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150156113ad578051611164906138d4565b156111e6576102ff838154811061117d5761117d6158a9565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa4909101556113ad565b60026111f06131fa565b6111fa91906158bf565b81602001516001600160601b031611156112c65760208101516102ff5460405160019233928792600080516020615efe833981519152926112419290918291600391615903565b60405180910390a46102ff838154811061125d5761125d6158a9565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec909101556113ad565b6000806112e4836000015184602001516001600160601b0316612f87565b91509150856102fe546112f79190615937565b821115611306575050506113c0565b6113108188615896565b965061131c8287615896565b9550600183600001516001600160a01b031686600080516020615efe8339815191528660200151866002600019604051611359949392919061594a565b60405180910390a46102ff8581548110611375576113756158a9565b600091825260208220015582516113aa908361139a6102c6546001600160a01b031690565b6001600160a01b03169190613944565b50505b826113b78161596e565b935050506110ee565b836102fc60008282546113d39190615896565b92505081905550826102fe60008282546113ed9190615937565b909155506113fd90508484615896565b6102fd600082825461140f9190615937565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b60006110326139a7565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114a05760405162461bcd60e51b8152600401610d1590615987565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114e9600080516020615eb7833981519152546001600160a01b031690565b6001600160a01b03161461150f5760405162461bcd60e51b8152600401610d15906159d3565b61151881613a1d565b6040805160008082526020820190925261153491839190613a25565b50565b600033610cc981858561154a8383613281565b6115549190615896565b6133b3565b610292602052816000526040600020818154811061157657600080fd5b6000918252602090912001546001600160a01b03169150829050565b61159a61388c565b336115a4816138d4565b156115c15760405162461bcd60e51b8152600401610d1590615a1f565b6115ca33611cc4565b8211156115ff5760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546116149190615896565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169a9190615a3b565b101580156116ab57506102fe548411155b905081806116b65750805b6116e85760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116f53387612f87565b91509150806102fc600082825461170c9190615896565b92505081905550816102fe60008282546117269190615937565b9091555060019050336001600160a01b0316600019600080516020615efe833981519152898660026000196040516117619493929190615a54565b60405180910390a46117733382613b90565b61177d3383613cd7565b50505050505050565b61178e61388c565b33611798816138d4565b156117b55760405162461bcd60e51b8152600401610d1590615a1f565b60006102ff83815481106117cb576117cb6158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118475760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd60008282546118679190615937565b90915550506102ff805484908110611881576118816158a9565b6000918252602082200155600181600001516001600160a01b031684600080516020615efe8339815191528460200151856020015160016000196040516118cb9493929190615903565b60405180910390a46118ee816000015182602001516001600160601b0316613d04565b505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361193b5760405162461bcd60e51b8152600401610d1590615987565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611984600080516020615eb7833981519152546001600160a01b031690565b6001600160a01b0316146119aa5760405162461bcd60e51b8152600401610d15906159d3565b6119b382613a1d565b6119bf82826001613a25565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a635760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615eb783398151915290565b6103018181548110611a8757600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613dd9565b611ac46134d7565b610302546000199060005b81811015611b2957836001600160a01b03166103028281548110611af557611af56158a9565b6000918252602090912001546001600160a01b031603611b1757809250611b29565b80611b218161596e565b915050611acf565b506000198213611b615760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b6f600183615937565b81548110611b7f57611b7f6158a9565b60009182526020909120015461030280546001600160a01b039092169184908110611bac57611bac6158a9565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611bec57611bec615a6f565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611c1b6134d7565b60405163433e3bad60e11b8152610290600482015261ffff82166024820152730165878A594ca255338adfa4d48449f69242Eb8F9063867c775a9060440160006040518083038186803b158015611c7157600080fd5b505af4158015611c85573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611ccf8261312c565b611cd883612572565b610ccf9190615896565b611cea6134d7565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d625760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d6a61388c565b60006102ff8281548110611d8057611d806158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611df15760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611dfc906138d4565b15611e2f5760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611e396131fa565b611e4391906158bf565b81602001516001600160601b031611611e845760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611ea2836000015184602001516001600160601b0316612f87565b915091506000611ebb6102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190615a3b565b9050806102fe54611f3a9190615896565b831115611f6f5760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f829190615896565b9250508190555083602001516001600160601b03166102fd6000828254611fa99190615937565b9091555050610300548503611fcf576103008054906000611fc98361596e565b91905055505b600184600001516001600160a01b031686600080516020615efe833981519152876020015187600260001960405161200a949392919061594a565b60405180910390a46102ff8581548110612026576120266158a9565b600091825260208220015580831161206857612063338551856120526102c6546001600160a01b031690565b6001600160a01b0316929190613e48565b6120c5565b60006120748285615937565b9050806102fe60008282546120899190615937565b909155506120a99050338651846120526102c6546001600160a01b031690565b84516120c3908261139a6102c6546001600160a01b031690565b505b6120cd613e80565b5050505050565b6102fb546001600160a01b0316336001600160a01b03161461211e5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b61212661388c565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190615a3b565b8111156121d65760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe546121e79190615896565b90506121f16131fa565b8111156122265760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546122399190615896565b909155506119bf90503330846120526102c6546001600160a01b031690565b6122606134d7565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122b35760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119bf8282613ee9565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a85565b61233461388c565b8161233e816138d4565b1561235b5760405162461bcd60e51b8152600401610d1590615a1f565b81612365816138d4565b156123825760405162461bcd60e51b8152600401610d1590615a1f565b6001600160a01b038481166000908152610291602052604090205416156123d15760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b03841661240d5760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166124495760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124905760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b6124986122bd565b6001600160a01b0316336001600160a01b031614806124bf5750336001600160a01b038516145b6124f15760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124fc846001613fdb565b612507836001613fdb565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c389061577c565b6001600160a01b038116600090815260976020526040812054610ccf565b6125986134d7565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125f361388c565b336125fd816138d4565b1561261a5760405162461bcd60e51b8152600401610d1590615a1f565b61262333611cc4565b8211156126585760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b038211156126955760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660aa87bee538000146126d15760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b600060405180604001604052806126e53390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561275d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127819190615a3b565b101580156127925750600061030054115b156128005761030080549060006127a883615aa2565b9190505550610300549050816102ff82815481106127c8576127c86158a9565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561286a565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9092019190915590546128679190615937565b90505b836102fd600082825461287d9190615896565b9091555060019050336001600160a01b031682600080516020615efe833981519152878860006000196040516128b69493929190615a54565b60405180910390a46128c83385613b90565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d8060008114612916576040519150601f19603f3d011682016040523d82523d6000602084013e61291b565b606091505b50509050806120cd5760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b600033816129608286613281565b9050838110156129c05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b6129cd82868684036133b3565b506001949350505050565b6129e06134d7565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b612a0b61388c565b81612a15816138d4565b15612a325760405162461bcd60e51b8152600401610d1590615a1f565b81612a3c816138d4565b15612a595760405162461bcd60e51b8152600401610d1590615a1f565b6001600160a01b038416612a955760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612ad15760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612ad96122bd565b6001600160a01b0316336001600160a01b03161480612b005750336001600160a01b038516145b612b325760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b855760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b90846001613fdb565b612b9b836001613fdb565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612c26576001600160a01b0385811660009081526102926020526040902080549188169183908110612bf257612bf26158a9565b6000918252602090912001546001600160a01b031603612c1457809150612c26565b80612c1e8161596e565b915050612ba1565b506000811215612c3857612c38615ab9565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c7c90600190615937565b81548110612c8c57612c8c6158a9565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612cca57612cca6158a9565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612d1057612d10615a6f565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc98185856136d0565b612d4f6134d7565b60006102fe54612d686102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd29190615a3b565b612ddc9190615937565b905060008111612e145760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b611534612e2a6102c6546001600160a01b031690565b82613ee9565b612e3861388c565b33612e42816138d4565b15612e5f5760405162461bcd60e51b8152600401610d1590615a1f565b81612e736102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190615a3b565b1015612f1e5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612f319190615896565b9091555060009050336001600160a01b0316600019600080516020615efe83398151915285866002600019604051612f6c9493929190615a54565b60405180910390a4612f7e33836140b0565b506119bf613e80565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ffe9190615a3b565b1061300e5750819050600061309c565b600061302b61302661028e546001600160a01b031690565b614131565b90506000613039858361419e565b6102fb5490915060009061305a90600160a01b900463ffffffff16846141dc565b90506000613069606485614208565b6130738385615acf565b61307d91906158bf565b90506130898185614236565b94506130958588615937565b9550505050505b9250929050565b6102ff8181548110611a8757600080fd5b60405163106d64cf60e31b81526102906004820152600090730165878A594ca255338adfa4d48449f69242Eb8F9063836b267890602401602060405180830381865af4158015613108573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615ae6565b6000610ccf82600161426d565b6131416134d7565b60006102fc541161317a5760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131b65760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe60008282546131cc9190615937565b90915550506102fc805460009091556115346131e66122bd565b8261139a6102c6546001600160a01b031690565b60008061321361302661028e546001600160a01b031690565b9050600061322861322261100c565b8361419e565b6102fb5490915060009061324990600160c01b900463ffffffff16846141dc565b90506000613258606485614208565b6132628385615acf565b61326c91906158bf565b90506132788185614236565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6132b46134d7565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b61030281815481106132ec57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6133196134d7565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b61334e6134d7565b61271063ffffffff8216111561338c5760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166134155760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134765760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b336134e06122bd565b6001600160a01b0316146135365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661355f5760405162461bcd60e51b8152600401610d1590615b03565b61356a8585856147d3565b613574828261482d565b6120cd61485e565b600054610100900460ff166135a35760405162461bcd60e51b8152600401610d1590615b03565b61153481614885565b600054610100900460ff166135d35760405162461bcd60e51b8152600401610d1590615b03565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b8152610290600482015260006024820152730165878A594ca255338adfa4d48449f69242Eb8F9063867c775a9060440160006040518083038186803b15801561364257600080fd5b505af41580156120cd573d6000803e3d6000fd5b60006136628484613281565b905060001981146136ca57818110156136bd5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136ca84848484036133b3565b50505050565b6001600160a01b0383166137345760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137965760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b6137a1838383614927565b6001600160a01b038316600090815260976020526040902054818110156138195760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138799086815260200190565b60405180910390a36136ca848484614966565b613894611ab2565b156135365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa158015613920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615b4e565b6040516001600160a01b0383166024820152604481018290526118ee90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a6f565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa925050508015613a0e575060408051601f3d908101601f19168201909252613a0b91810190615b70565b60015b613a185750601290565b919050565b6115346134d7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a58576118ee83614b44565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613ab2575060408051601f3d908101601f19168201909252613aaf91810190615a3b565b60015b613b155760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615eb78339815191528114613b845760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118ee838383614be0565b6001600160a01b038216613bf05760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613bfc82600083614927565b6001600160a01b03821660009081526097602052604090205481811015613c705760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118ee83600084614966565b6000613ce33383613b90565b6102c654613cfb906001600160a01b03168484613944565b50600192915050565b6001600160a01b038216613d5a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d6660008383614927565b8060996000828254613d789190615896565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36119bf60008383614966565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613e24573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b4e565b6040516001600160a01b03808516602483015283166044820152606481018290526136ca9085906323b872dd60e01b90608401613970565b6000613e8a6131fa565b9050806102fe5411613e995750565b6000816102fe54613eaa9190615937565b9050806102fe6000828254613ebf9190615937565b90915550506102fb546119bf906001600160a01b03168261139a6102c6546001600160a01b031690565b613ef16134d7565b60008111613f275760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f939190615a3b565b1015613fc75760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118ee6001600160a01b0382163384613944565b6102935460ff1615613feb575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603614019575050565b6001600160a01b0380831660009081526102916020526040902054168015614045576118ee8183613fdb565b6000614051848461426d565b905080156140a757610293805460ff1916600117905560006140738583614c05565b610293805460ff191690559050806140a5576001600160a01b038516600090815261028f602052604090206003018290555b505b6136ca84614c5c565b60003330810361410e5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c654614127906001600160a01b0316823086613e48565b610cc98484613d04565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141959190615b70565b60ff1692915050565b600060038210156141d0576141b4826006615937565b6141bf90600a615c77565b6141c99084615acf565b9050610ccf565b611087836103e8615acf565b600060038210156141f3576141c9836103e8615acf565b6141fe82600a615c77565b6110879084615acf565b60006003821015614220576141c983620f4240615acf565b61422b826003615896565b6141fe90600a615c77565b600060038210156142615761424c826006615937565b61425790600a615c77565b6141c990846158bf565b6110876103e8846158bf565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff168486015260608201939093529182526003015491810191909152816142de85614dbe565b82515190915064ffffffffff1615806142f5575080155b1561430557600092505050610ccf565b815160200151604051630b27cfb160e31b8152600090730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d889061434990610290908690600401615c83565b6040805180830381865af4158015614365573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143899190615ca7565b60405163038255fd60e11b81526102906004820152909150600090730165878A594ca255338adfa4d48449f69242Eb8F90630704abfa906024016040805180830381865af41580156143df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144039190615cf2565b905084602001519550730165878A594ca255338adfa4d48449f69242Eb8F634ead0c5384836040518363ffffffff1660e01b8152600401614445929190615d1e565b602060405180830381865af4158015614462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144869190615b4e565b61479757604051633e1e5c5360e11b8152600090730165878A594ca255338adfa4d48449f69242Eb8F90637c3cb8a6906144c4908790600401615d52565b6040805180830381865af41580156144e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145049190615cf2565b604051630b27cfb160e31b8152909150600090730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d889061454590610290908690600401615c83565b6040805180830381865af4158015614561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145859190615ca7565b875151602082015186519293506145b3928c6145a25760006145a4565b8b5b6145ae908b615896565b614e67565b6145bd9089615896565b97505b819450809350730165878A594ca255338adfa4d48449f69242Eb8F634ead0c5386856040518363ffffffff1660e01b81526004016145ff929190615d1e565b602060405180830381865af415801561461c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146409190615b4e565b61476a57604051633e1e5c5360e11b8152730165878A594ca255338adfa4d48449f69242Eb8F90637c3cb8a69061467b908890600401615d52565b6040805180830381865af4158015614697573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146bb9190615cf2565b604051630b27cfb160e31b8152909250730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d88906146f990610290908690600401615c83565b6040805180830381865af4158015614715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147399190615ca7565b90506147598460200151826020015186600001518c6145a25760006145a4565b6147639089615896565b97506145c0565b61478484602001514286600001518c6145a25760006145a4565b61478e9089615896565b975050506147c8565b84515182516147bb919042908a6147af5760006147b1565b895b6145ae9089615896565b6147c59087615896565b95505b505050505092915050565b600054610100900460ff166147fa5760405162461bcd60e51b8152600401610d1590615b03565b61480261485e565b61480b83614f53565b614813614f83565b61481c82614fb2565b61482581614ffc565b6118ee61485e565b600054610100900460ff166148545760405162461bcd60e51b8152600401610d1590615b03565b6119bf8282615046565b600054610100900460ff166135365760405162461bcd60e51b8152600401610d1590615b03565b600054610100900460ff166148ac5760405162461bcd60e51b8152600401610d1590615b03565b306001600160a01b038216036149045760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b614932838383615086565b6001600160a01b0383161561494c5761494c836001613fdb565b6001600160a01b038216156118ee576118ee826001613fdb565b6001600160a01b038316158061498357506001600160a01b038216155b156149c3577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f6149b161100c565b60405190815260200160405180910390a15b60005b610302548110156136ca5761030281815481106149e5576149e56158a9565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b158015614a4457600080fd5b505af1158015614a58573d6000803e3d6000fd5b505050508080614a679061596e565b9150506149c6565b6000614ac4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150e79092919063ffffffff16565b9050805160001480614ae5575080806020019051810190614ae59190615b4e565b6118ee5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614bb15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615eb783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614be9836150f6565b600082511180614bf65750805b156118ee576136ca8383615136565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614c3b85612572565b60408051918252602082018690520160405180910390a2613cfb8383613d04565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b81526102906004820152730165878A594ca255338adfa4d48449f69242Eb8F90630704abfa906024016040805180830381865af4158015614cda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cfe9190615cf2565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b038216600090815261029260205260409020548110156119bf576001600160a01b0382166000908152610292602052604090208054614dac919083908110614d9257614d926158a9565b6000918252602090912001546001600160a01b0316614c5c565b80614db68161596e565b915050614d41565b6000614dc98261515b565b614dd39082615896565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e61576001600160a01b0383166000908152610292602052604090208054614e43919083908110614e2957614e296158a9565b6000918252602090912001546001600160a01b0316614dbe565b614e4d9083615896565b915080614e598161596e565b915050614dd8565b50919050565b600080614e8061302661028e546001600160a01b031690565b90506000614e9e614e918888615d6f565b64ffffffffff1683614208565b90506000614eb06301e1338084614208565b614ebb600185614208565b614ec59084615acf565b614ecf91906158bf565b90506000614ee18761ffff16856141dc565b90506000614ef0600186614208565b614efa8385615acf565b614f0491906158bf565b90506000614f12888761419e565b90506000614f21606488614208565b614f2b8484615acf565b614f3591906158bf565b9050614f418188614236565b9750505050505050505b949350505050565b600054610100900460ff16614f7a5760405162461bcd60e51b8152600401610d1590615b03565b61153481615166565b600054610100900460ff16614faa5760405162461bcd60e51b8152600401610d1590615b03565b6135366151b0565b600054610100900460ff16614fd95760405162461bcd60e51b8152600401610d1590615b03565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150235760405162461bcd60e51b8152600401610d1590615b03565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661506d5760405162461bcd60e51b8152600401610d1590615b03565b609a6150798382615dda565b50609b6118ee8282615dda565b61508e61388c565b82615098816138d4565b156150b55760405162461bcd60e51b8152600401610d1590615a1f565b826150bf816138d4565b156150dc5760405162461bcd60e51b8152600401610d1590615a1f565b6120cd8585856151e3565b6060614f4b848460008561524b565b6150ff81614b44565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615ed760279139615326565b6000610ccf82612572565b600054610100900460ff1661518d5760405162461bcd60e51b8152600401610d1590615b03565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151d75760405162461bcd60e51b8152600401610d1590615b03565b60c9805460ff19169055565b6151eb611ab2565b156118ee5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152ac5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152c89190615e9a565b60006040518083038185875af1925050503d8060008114615305576040519150601f19603f3d011682016040523d82523d6000602084013e61530a565b606091505b509150915061531b8783838761539e565b979650505050505050565b6060600080856001600160a01b0316856040516153439190615e9a565b600060405180830381855af49150503d806000811461537e576040519150601f19603f3d011682016040523d82523d6000602084013e615383565b606091505b50915091506153948683838761539e565b9695505050505050565b6060831561540d578251600003615406576001600160a01b0385163b6154065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614f4b565b614f4b83838151156154225781518083602001fd5b8060405162461bcd60e51b8152600401610d159190615460565b60005b8381101561545757818101518382015260200161543f565b50506000910152565b602081526000825180602084015261547f81604085016020870161543c565b601f01601f19169190910160400192915050565b6001600160a01b038116811461153457600080fd5b600080604083850312156154bb57600080fd5b82356154c681615493565b946020939093013593505050565b6000602082840312156154e657600080fd5b813561108781615493565b600080600080600060a0868803121561550957600080fd5b853561551481615493565b9450602086013561552481615493565b9350604086013561553481615493565b9250606086013561554481615493565b9150608086013561555481615493565b809150509295509295909350565b60008060006060848603121561557757600080fd5b833561558281615493565b9250602084013561559281615493565b929592945050506040919091013590565b6000602082840312156155b557600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155f5576155f56155bc565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715615624576156246155bc565b604052919050565b600067ffffffffffffffff821115615646576156466155bc565b50601f01601f191660200190565b6000806040838503121561566757600080fd5b823561567281615493565b9150602083013567ffffffffffffffff81111561568e57600080fd5b8301601f8101851361569f57600080fd5b80356156b26156ad8261562c565b6155fb565b8181528660208385010111156156c757600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff8116811461153457600080fd5b60006020828403121561570957600080fd5b8135611087816156e7565b6000806040838503121561572757600080fd5b823561573281615493565b9150602083013561574281615493565b809150509250929050565b63ffffffff8116811461153457600080fd5b60006020828403121561577157600080fd5b81356110878161574d565b600181811c9082168061579057607f821691505b602082108103614e6157634e487b7160e01b600052602260045260246000fd5b6000602082840312156157c257600080fd5b815167ffffffffffffffff8111156157d957600080fd5b8201601f810184136157ea57600080fd5b80516157f86156ad8261562c565b81815285602083850101111561580d57600080fd5b61581e82602083016020860161543c565b95945050505050565b6702632b233b4ba3c960c51b81526000825161584a81600885016020870161543c565b9190910160080192915050565b601360fa1b81526000825161587381600185016020870161543c565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf615880565b634e487b7160e01b600052603260045260246000fd5b6000826158dc57634e487b7160e01b600052601260045260246000fd5b500490565b600481106158ff57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b038581168252841660208201526080810161592860408301856158e1565b82606083015295945050505050565b81810381811115610ccf57610ccf615880565b6001600160601b0385168152602081018490526080810161592860408301856158e1565b60006001820161598057615980615880565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b600060208284031215615a4d57600080fd5b5051919050565b848152602081018490526080810161592860408301856158e1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a9757600080fd5b815161108781615493565b600081615ab157615ab1615880565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf615880565b600060208284031215615af857600080fd5b8151611087816156e7565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615b6057600080fd5b8151801515811461108757600080fd5b600060208284031215615b8257600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615bce578160001904821115615bb457615bb4615880565b80851615615bc157918102915b93841c9390800290615b98565b509250929050565b600082615be557506001610ccf565b81615bf257506000610ccf565b8160018114615c085760028114615c1257615c2e565b6001915050610ccf565b60ff841115615c2357615c23615880565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615c51575081810a610ccf565b615c5b8383615b93565b8060001904821115615c6f57615c6f615880565b029392505050565b60006110878383615bd6565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615cb957600080fd5b615cc16155d2565b8251615ccc816156e7565b8152602083015164ffffffffff81168114615ce657600080fd5b60208201529392505050565b600060408284031215615d0457600080fd5b615d0c6155d2565b825181526020830151615ce68161574d565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d8d57615d8d615880565b5092915050565b601f8211156118ee57600081815260208120601f850160051c81016020861015615dbb5750805b601f850160051c820191505b8181101561100457828155600101615dc7565b815167ffffffffffffffff811115615df457615df46155bc565b615e0881615e02845461577c565b84615d94565b602080601f831160018114615e3d5760008415615e255750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e6c57888601518255948401946001909101908401615e4d565b5085821015615e8a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615eac81846020870161543c565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564d58e94604d90293a1c1ad95bfe6a6e6c352c33c5774a4b6b4f4b6f7460da29c5a2646970667358221220dd0b851f900961e32e37a6ae5b5853db7ebab6f11c303fcce7b61d5ad4a86eea64736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b6040516104009190615460565b60405180910390f35b34801561041557600080fd5b506104296104243660046154a8565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b506104596104543660046154d4565b610cd5565b005b34801561046757600080fd5b506104596104763660046154d4565b610d41565b34801561048757600080fd5b506104596104963660046154f1565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f03660046154a8565b611037565b34801561050157600080fd5b50610429610510366004615562565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b506104296105453660046154a8565b61141d565b34801561055657600080fd5b5061055f61144e565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c3660046154d4565b611458565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e53660046154a8565b611537565b3480156105f657600080fd5b506105b26106053660046154a8565b611559565b34801561061657600080fd5b506104596106253660046155a3565b611592565b34801561063657600080fd5b506104596106453660046155a3565b611786565b610459610658366004615654565b6118f3565b34801561066957600080fd5b506104b06119c3565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a43660046155a3565b611a76565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611ab2565b3480156106f157600080fd5b506104596107003660046154d4565b611abc565b34801561071157600080fd5b506104596107203660046156f7565b611c13565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f3660046154d4565b611cc4565b34801561077057600080fd5b50610459611ce2565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c23660046155a3565b611d18565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b506104596108013660046155a3565b6120d4565b34801561081257600080fd5b506104596108213660046154a8565b612258565b34801561083257600080fd5b506105b26108413660046154d4565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b26122bd565b34801561087e57600080fd5b5061045961088d366004615714565b61232c565b34801561089e57600080fd5b506103f3612563565b3480156108b357600080fd5b506104b06108c23660046154d4565b612572565b3480156108d357600080fd5b506104596108e23660046154d4565b612590565b6104596108f53660046155a3565b6125eb565b34801561090657600080fd5b506104296109153660046154a8565b612952565b34801561092657600080fd5b506104596109353660046154d4565b6129d8565b34801561094657600080fd5b50610459610955366004615714565b612a03565b34801561096657600080fd5b506104296109753660046154a8565b612d39565b34801561098657600080fd5b50610459612d47565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb3660046155a3565b612e30565b3480156109dc57600080fd5b506109f06109eb3660046154a8565b612f87565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a203660046155a3565b6130a3565b348015610a3157600080fd5b50610a3a6130b4565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae23660046154d4565b61312c565b348015610af357600080fd5b50610459613139565b348015610b0857600080fd5b506104b06131fa565b348015610b1d57600080fd5b506104b0610b2c366004615714565b613281565b348015610b3d57600080fd5b50610459610b4c36600461575f565b6132ac565b348015610b5d57600080fd5b506105b2610b6c3660046155a3565b6132db565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b0613306565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be53660046154d4565b613311565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461575f565b613346565b6060609a8054610c389061577c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c649061577c565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc98185856133b3565b60019150505b92915050565b610cdd6134d7565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d496134d7565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed091908101906157b0565b9050610f1d87878784604051602001610ee99190615827565b60405160208183030381529060405285604051602001610f099190615857565b604051602081830303815290604052613538565b610f268361357c565b610f2f306135ac565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f736122bd565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c6122bd565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e613306565b6110289190615896565b6110329190615896565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613656565b6110818585856136d0565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e061388c565b610300546102ff5460009182915b808210156113c05761afc85a106113c05760006102ff8381548110611115576111156158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150156113ad578051611164906138d4565b156111e6576102ff838154811061117d5761117d6158a9565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa4909101556113ad565b60026111f06131fa565b6111fa91906158bf565b81602001516001600160601b031611156112c65760208101516102ff5460405160019233928792600080516020615efe833981519152926112419290918291600391615903565b60405180910390a46102ff838154811061125d5761125d6158a9565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec909101556113ad565b6000806112e4836000015184602001516001600160601b0316612f87565b91509150856102fe546112f79190615937565b821115611306575050506113c0565b6113108188615896565b965061131c8287615896565b9550600183600001516001600160a01b031686600080516020615efe8339815191528660200151866002600019604051611359949392919061594a565b60405180910390a46102ff8581548110611375576113756158a9565b600091825260208220015582516113aa908361139a6102c6546001600160a01b031690565b6001600160a01b03169190613944565b50505b826113b78161596e565b935050506110ee565b836102fc60008282546113d39190615896565b92505081905550826102fe60008282546113ed9190615937565b909155506113fd90508484615896565b6102fd600082825461140f9190615937565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b60006110326139a7565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114a05760405162461bcd60e51b8152600401610d1590615987565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114e9600080516020615eb7833981519152546001600160a01b031690565b6001600160a01b03161461150f5760405162461bcd60e51b8152600401610d15906159d3565b61151881613a1d565b6040805160008082526020820190925261153491839190613a25565b50565b600033610cc981858561154a8383613281565b6115549190615896565b6133b3565b610292602052816000526040600020818154811061157657600080fd5b6000918252602090912001546001600160a01b03169150829050565b61159a61388c565b336115a4816138d4565b156115c15760405162461bcd60e51b8152600401610d1590615a1f565b6115ca33611cc4565b8211156115ff5760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546116149190615896565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169a9190615a3b565b101580156116ab57506102fe548411155b905081806116b65750805b6116e85760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116f53387612f87565b91509150806102fc600082825461170c9190615896565b92505081905550816102fe60008282546117269190615937565b9091555060019050336001600160a01b0316600019600080516020615efe833981519152898660026000196040516117619493929190615a54565b60405180910390a46117733382613b90565b61177d3383613cd7565b50505050505050565b61178e61388c565b33611798816138d4565b156117b55760405162461bcd60e51b8152600401610d1590615a1f565b60006102ff83815481106117cb576117cb6158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118475760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd60008282546118679190615937565b90915550506102ff805484908110611881576118816158a9565b6000918252602082200155600181600001516001600160a01b031684600080516020615efe8339815191528460200151856020015160016000196040516118cb9493929190615903565b60405180910390a46118ee816000015182602001516001600160601b0316613d04565b505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361193b5760405162461bcd60e51b8152600401610d1590615987565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611984600080516020615eb7833981519152546001600160a01b031690565b6001600160a01b0316146119aa5760405162461bcd60e51b8152600401610d15906159d3565b6119b382613a1d565b6119bf82826001613a25565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a635760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615eb783398151915290565b6103018181548110611a8757600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613dd9565b611ac46134d7565b610302546000199060005b81811015611b2957836001600160a01b03166103028281548110611af557611af56158a9565b6000918252602090912001546001600160a01b031603611b1757809250611b29565b80611b218161596e565b915050611acf565b506000198213611b615760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b6f600183615937565b81548110611b7f57611b7f6158a9565b60009182526020909120015461030280546001600160a01b039092169184908110611bac57611bac6158a9565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611bec57611bec615a6f565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611c1b6134d7565b60405163433e3bad60e11b8152610290600482015261ffff8216602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b158015611c7157600080fd5b505af4158015611c85573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611ccf8261312c565b611cd883612572565b610ccf9190615896565b611cea6134d7565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d625760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d6a61388c565b60006102ff8281548110611d8057611d806158a9565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611df15760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611dfc906138d4565b15611e2f5760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611e396131fa565b611e4391906158bf565b81602001516001600160601b031611611e845760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611ea2836000015184602001516001600160601b0316612f87565b915091506000611ebb6102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190615a3b565b9050806102fe54611f3a9190615896565b831115611f6f5760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f829190615896565b9250508190555083602001516001600160601b03166102fd6000828254611fa99190615937565b9091555050610300548503611fcf576103008054906000611fc98361596e565b91905055505b600184600001516001600160a01b031686600080516020615efe833981519152876020015187600260001960405161200a949392919061594a565b60405180910390a46102ff8581548110612026576120266158a9565b600091825260208220015580831161206857612063338551856120526102c6546001600160a01b031690565b6001600160a01b0316929190613e48565b6120c5565b60006120748285615937565b9050806102fe60008282546120899190615937565b909155506120a99050338651846120526102c6546001600160a01b031690565b84516120c3908261139a6102c6546001600160a01b031690565b505b6120cd613e80565b5050505050565b6102fb546001600160a01b0316336001600160a01b03161461211e5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b61212661388c565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190615a3b565b8111156121d65760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe546121e79190615896565b90506121f16131fa565b8111156122265760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546122399190615896565b909155506119bf90503330846120526102c6546001600160a01b031690565b6122606134d7565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122b35760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119bf8282613ee9565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a85565b61233461388c565b8161233e816138d4565b1561235b5760405162461bcd60e51b8152600401610d1590615a1f565b81612365816138d4565b156123825760405162461bcd60e51b8152600401610d1590615a1f565b6001600160a01b038481166000908152610291602052604090205416156123d15760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b03841661240d5760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166124495760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124905760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b6124986122bd565b6001600160a01b0316336001600160a01b031614806124bf5750336001600160a01b038516145b6124f15760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124fc846001613fdb565b612507836001613fdb565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c389061577c565b6001600160a01b038116600090815260976020526040812054610ccf565b6125986134d7565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125f361388c565b336125fd816138d4565b1561261a5760405162461bcd60e51b8152600401610d1590615a1f565b61262333611cc4565b8211156126585760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b038211156126955760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660aa87bee538000146126d15760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b600060405180604001604052806126e53390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561275d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127819190615a3b565b101580156127925750600061030054115b156128005761030080549060006127a883615aa2565b9190505550610300549050816102ff82815481106127c8576127c86158a9565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561286a565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9092019190915590546128679190615937565b90505b836102fd600082825461287d9190615896565b9091555060019050336001600160a01b031682600080516020615efe833981519152878860006000196040516128b69493929190615a54565b60405180910390a46128c83385613b90565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d8060008114612916576040519150601f19603f3d011682016040523d82523d6000602084013e61291b565b606091505b50509050806120cd5760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b600033816129608286613281565b9050838110156129c05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b6129cd82868684036133b3565b506001949350505050565b6129e06134d7565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b612a0b61388c565b81612a15816138d4565b15612a325760405162461bcd60e51b8152600401610d1590615a1f565b81612a3c816138d4565b15612a595760405162461bcd60e51b8152600401610d1590615a1f565b6001600160a01b038416612a955760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612ad15760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612ad96122bd565b6001600160a01b0316336001600160a01b03161480612b005750336001600160a01b038516145b612b325760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b855760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b90846001613fdb565b612b9b836001613fdb565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612c26576001600160a01b0385811660009081526102926020526040902080549188169183908110612bf257612bf26158a9565b6000918252602090912001546001600160a01b031603612c1457809150612c26565b80612c1e8161596e565b915050612ba1565b506000811215612c3857612c38615ab9565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c7c90600190615937565b81548110612c8c57612c8c6158a9565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612cca57612cca6158a9565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612d1057612d10615a6f565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc98185856136d0565b612d4f6134d7565b60006102fe54612d686102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd29190615a3b565b612ddc9190615937565b905060008111612e145760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b611534612e2a6102c6546001600160a01b031690565b82613ee9565b612e3861388c565b33612e42816138d4565b15612e5f5760405162461bcd60e51b8152600401610d1590615a1f565b81612e736102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190615a3b565b1015612f1e5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612f319190615896565b9091555060009050336001600160a01b0316600019600080516020615efe83398151915285866002600019604051612f6c9493929190615a54565b60405180910390a4612f7e33836140b0565b506119bf613e80565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ffe9190615a3b565b1061300e5750819050600061309c565b600061302b61302661028e546001600160a01b031690565b614131565b90506000613039858361419e565b6102fb5490915060009061305a90600160a01b900463ffffffff16846141dc565b90506000613069606485614208565b6130738385615acf565b61307d91906158bf565b90506130898185614236565b94506130958588615937565b9550505050505b9250929050565b6102ff8181548110611a8757600080fd5b60405163106d64cf60e31b8152610290600482015260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063836b267890602401602060405180830381865af4158015613108573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615ae6565b6000610ccf82600161426d565b6131416134d7565b60006102fc541161317a5760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131b65760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe60008282546131cc9190615937565b90915550506102fc805460009091556115346131e66122bd565b8261139a6102c6546001600160a01b031690565b60008061321361302661028e546001600160a01b031690565b9050600061322861322261100c565b8361419e565b6102fb5490915060009061324990600160c01b900463ffffffff16846141dc565b90506000613258606485614208565b6132628385615acf565b61326c91906158bf565b90506132788185614236565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6132b46134d7565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b61030281815481106132ec57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6133196134d7565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b61334e6134d7565b61271063ffffffff8216111561338c5760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166134155760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134765760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b336134e06122bd565b6001600160a01b0316146135365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661355f5760405162461bcd60e51b8152600401610d1590615b03565b61356a8585856147d3565b613574828261482d565b6120cd61485e565b600054610100900460ff166135a35760405162461bcd60e51b8152600401610d1590615b03565b61153481614885565b600054610100900460ff166135d35760405162461bcd60e51b8152600401610d1590615b03565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b815261029060048201526000602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b15801561364257600080fd5b505af41580156120cd573d6000803e3d6000fd5b60006136628484613281565b905060001981146136ca57818110156136bd5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136ca84848484036133b3565b50505050565b6001600160a01b0383166137345760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137965760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b6137a1838383614927565b6001600160a01b038316600090815260976020526040902054818110156138195760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138799086815260200190565b60405180910390a36136ca848484614966565b613894611ab2565b156135365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa158015613920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615b4e565b6040516001600160a01b0383166024820152604481018290526118ee90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a6f565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa925050508015613a0e575060408051601f3d908101601f19168201909252613a0b91810190615b70565b60015b613a185750601290565b919050565b6115346134d7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a58576118ee83614b44565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613ab2575060408051601f3d908101601f19168201909252613aaf91810190615a3b565b60015b613b155760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615eb78339815191528114613b845760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118ee838383614be0565b6001600160a01b038216613bf05760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613bfc82600083614927565b6001600160a01b03821660009081526097602052604090205481811015613c705760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118ee83600084614966565b6000613ce33383613b90565b6102c654613cfb906001600160a01b03168484613944565b50600192915050565b6001600160a01b038216613d5a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d6660008383614927565b8060996000828254613d789190615896565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36119bf60008383614966565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613e24573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b4e565b6040516001600160a01b03808516602483015283166044820152606481018290526136ca9085906323b872dd60e01b90608401613970565b6000613e8a6131fa565b9050806102fe5411613e995750565b6000816102fe54613eaa9190615937565b9050806102fe6000828254613ebf9190615937565b90915550506102fb546119bf906001600160a01b03168261139a6102c6546001600160a01b031690565b613ef16134d7565b60008111613f275760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f939190615a3b565b1015613fc75760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118ee6001600160a01b0382163384613944565b6102935460ff1615613feb575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603614019575050565b6001600160a01b0380831660009081526102916020526040902054168015614045576118ee8183613fdb565b6000614051848461426d565b905080156140a757610293805460ff1916600117905560006140738583614c05565b610293805460ff191690559050806140a5576001600160a01b038516600090815261028f602052604090206003018290555b505b6136ca84614c5c565b60003330810361410e5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c654614127906001600160a01b0316823086613e48565b610cc98484613d04565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614171573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141959190615b70565b60ff1692915050565b600060038210156141d0576141b4826006615937565b6141bf90600a615c77565b6141c99084615acf565b9050610ccf565b611087836103e8615acf565b600060038210156141f3576141c9836103e8615acf565b6141fe82600a615c77565b6110879084615acf565b60006003821015614220576141c983620f4240615acf565b61422b826003615896565b6141fe90600a615c77565b600060038210156142615761424c826006615937565b61425790600a615c77565b6141c990846158bf565b6110876103e8846158bf565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff168486015260608201939093529182526003015491810191909152816142de85614dbe565b82515190915064ffffffffff1615806142f5575080155b1561430557600092505050610ccf565b815160200151604051630b27cfb160e31b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d889061434990610290908690600401615c83565b6040805180830381865af4158015614365573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143899190615ca7565b60405163038255fd60e11b8152610290600482015290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af41580156143df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144039190615cf2565b90508460200151955073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5384836040518363ffffffff1660e01b8152600401614445929190615d1e565b602060405180830381865af4158015614462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144869190615b4e565b61479757604051633e1e5c5360e11b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a6906144c4908790600401615d52565b6040805180830381865af41580156144e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145049190615cf2565b604051630b27cfb160e31b815290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d889061454590610290908690600401615c83565b6040805180830381865af4158015614561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145859190615ca7565b875151602082015186519293506145b3928c6145a25760006145a4565b8b5b6145ae908b615896565b614e67565b6145bd9089615896565b97505b81945080935073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5386856040518363ffffffff1660e01b81526004016145ff929190615d1e565b602060405180830381865af415801561461c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146409190615b4e565b61476a57604051633e1e5c5360e11b815273__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a69061467b908890600401615d52565b6040805180830381865af4158015614697573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146bb9190615cf2565b604051630b27cfb160e31b815290925073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906146f990610290908690600401615c83565b6040805180830381865af4158015614715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147399190615ca7565b90506147598460200151826020015186600001518c6145a25760006145a4565b6147639089615896565b97506145c0565b61478484602001514286600001518c6145a25760006145a4565b61478e9089615896565b975050506147c8565b84515182516147bb919042908a6147af5760006147b1565b895b6145ae9089615896565b6147c59087615896565b95505b505050505092915050565b600054610100900460ff166147fa5760405162461bcd60e51b8152600401610d1590615b03565b61480261485e565b61480b83614f53565b614813614f83565b61481c82614fb2565b61482581614ffc565b6118ee61485e565b600054610100900460ff166148545760405162461bcd60e51b8152600401610d1590615b03565b6119bf8282615046565b600054610100900460ff166135365760405162461bcd60e51b8152600401610d1590615b03565b600054610100900460ff166148ac5760405162461bcd60e51b8152600401610d1590615b03565b306001600160a01b038216036149045760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b614932838383615086565b6001600160a01b0383161561494c5761494c836001613fdb565b6001600160a01b038216156118ee576118ee826001613fdb565b6001600160a01b038316158061498357506001600160a01b038216155b156149c3577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f6149b161100c565b60405190815260200160405180910390a15b60005b610302548110156136ca5761030281815481106149e5576149e56158a9565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b158015614a4457600080fd5b505af1158015614a58573d6000803e3d6000fd5b505050508080614a679061596e565b9150506149c6565b6000614ac4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150e79092919063ffffffff16565b9050805160001480614ae5575080806020019051810190614ae59190615b4e565b6118ee5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614bb15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615eb783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614be9836150f6565b600082511180614bf65750805b156118ee576136ca8383615136565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614c3b85612572565b60408051918252602082018690520160405180910390a2613cfb8383613d04565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b8152610290600482015273__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af4158015614cda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cfe9190615cf2565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b038216600090815261029260205260409020548110156119bf576001600160a01b0382166000908152610292602052604090208054614dac919083908110614d9257614d926158a9565b6000918252602090912001546001600160a01b0316614c5c565b80614db68161596e565b915050614d41565b6000614dc98261515b565b614dd39082615896565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e61576001600160a01b0383166000908152610292602052604090208054614e43919083908110614e2957614e296158a9565b6000918252602090912001546001600160a01b0316614dbe565b614e4d9083615896565b915080614e598161596e565b915050614dd8565b50919050565b600080614e8061302661028e546001600160a01b031690565b90506000614e9e614e918888615d6f565b64ffffffffff1683614208565b90506000614eb06301e1338084614208565b614ebb600185614208565b614ec59084615acf565b614ecf91906158bf565b90506000614ee18761ffff16856141dc565b90506000614ef0600186614208565b614efa8385615acf565b614f0491906158bf565b90506000614f12888761419e565b90506000614f21606488614208565b614f2b8484615acf565b614f3591906158bf565b9050614f418188614236565b9750505050505050505b949350505050565b600054610100900460ff16614f7a5760405162461bcd60e51b8152600401610d1590615b03565b61153481615166565b600054610100900460ff16614faa5760405162461bcd60e51b8152600401610d1590615b03565b6135366151b0565b600054610100900460ff16614fd95760405162461bcd60e51b8152600401610d1590615b03565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150235760405162461bcd60e51b8152600401610d1590615b03565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661506d5760405162461bcd60e51b8152600401610d1590615b03565b609a6150798382615dda565b50609b6118ee8282615dda565b61508e61388c565b82615098816138d4565b156150b55760405162461bcd60e51b8152600401610d1590615a1f565b826150bf816138d4565b156150dc5760405162461bcd60e51b8152600401610d1590615a1f565b6120cd8585856151e3565b6060614f4b848460008561524b565b6150ff81614b44565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615ed760279139615326565b6000610ccf82612572565b600054610100900460ff1661518d5760405162461bcd60e51b8152600401610d1590615b03565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151d75760405162461bcd60e51b8152600401610d1590615b03565b60c9805460ff19169055565b6151eb611ab2565b156118ee5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152ac5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152c89190615e9a565b60006040518083038185875af1925050503d8060008114615305576040519150601f19603f3d011682016040523d82523d6000602084013e61530a565b606091505b509150915061531b8783838761539e565b979650505050505050565b6060600080856001600160a01b0316856040516153439190615e9a565b600060405180830381855af49150503d806000811461537e576040519150601f19603f3d011682016040523d82523d6000602084013e615383565b606091505b50915091506153948683838761539e565b9695505050505050565b6060831561540d578251600003615406576001600160a01b0385163b6154065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614f4b565b614f4b83838151156154225781518083602001fd5b8060405162461bcd60e51b8152600401610d159190615460565b60005b8381101561545757818101518382015260200161543f565b50506000910152565b602081526000825180602084015261547f81604085016020870161543c565b601f01601f19169190910160400192915050565b6001600160a01b038116811461153457600080fd5b600080604083850312156154bb57600080fd5b82356154c681615493565b946020939093013593505050565b6000602082840312156154e657600080fd5b813561108781615493565b600080600080600060a0868803121561550957600080fd5b853561551481615493565b9450602086013561552481615493565b9350604086013561553481615493565b9250606086013561554481615493565b9150608086013561555481615493565b809150509295509295909350565b60008060006060848603121561557757600080fd5b833561558281615493565b9250602084013561559281615493565b929592945050506040919091013590565b6000602082840312156155b557600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155f5576155f56155bc565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715615624576156246155bc565b604052919050565b600067ffffffffffffffff821115615646576156466155bc565b50601f01601f191660200190565b6000806040838503121561566757600080fd5b823561567281615493565b9150602083013567ffffffffffffffff81111561568e57600080fd5b8301601f8101851361569f57600080fd5b80356156b26156ad8261562c565b6155fb565b8181528660208385010111156156c757600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff8116811461153457600080fd5b60006020828403121561570957600080fd5b8135611087816156e7565b6000806040838503121561572757600080fd5b823561573281615493565b9150602083013561574281615493565b809150509250929050565b63ffffffff8116811461153457600080fd5b60006020828403121561577157600080fd5b81356110878161574d565b600181811c9082168061579057607f821691505b602082108103614e6157634e487b7160e01b600052602260045260246000fd5b6000602082840312156157c257600080fd5b815167ffffffffffffffff8111156157d957600080fd5b8201601f810184136157ea57600080fd5b80516157f86156ad8261562c565b81815285602083850101111561580d57600080fd5b61581e82602083016020860161543c565b95945050505050565b6702632b233b4ba3c960c51b81526000825161584a81600885016020870161543c565b9190910160080192915050565b601360fa1b81526000825161587381600185016020870161543c565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf615880565b634e487b7160e01b600052603260045260246000fd5b6000826158dc57634e487b7160e01b600052601260045260246000fd5b500490565b600481106158ff57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b038581168252841660208201526080810161592860408301856158e1565b82606083015295945050505050565b81810381811115610ccf57610ccf615880565b6001600160601b0385168152602081018490526080810161592860408301856158e1565b60006001820161598057615980615880565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b600060208284031215615a4d57600080fd5b5051919050565b848152602081018490526080810161592860408301856158e1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a9757600080fd5b815161108781615493565b600081615ab157615ab1615880565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf615880565b600060208284031215615af857600080fd5b8151611087816156e7565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615b6057600080fd5b8151801515811461108757600080fd5b600060208284031215615b8257600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615bce578160001904821115615bb457615bb4615880565b80851615615bc157918102915b93841c9390800290615b98565b509250929050565b600082615be557506001610ccf565b81615bf257506000610ccf565b8160018114615c085760028114615c1257615c2e565b6001915050610ccf565b60ff841115615c2357615c23615880565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615c51575081810a610ccf565b615c5b8383615b93565b8060001904821115615c6f57615c6f615880565b029392505050565b60006110878383615bd6565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615cb957600080fd5b615cc16155d2565b8251615ccc816156e7565b8152602083015164ffffffffff81168114615ce657600080fd5b60208201529392505050565b600060408284031215615d0457600080fd5b615d0c6155d2565b825181526020830151615ce68161574d565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d8d57615d8d615880565b5092915050565b601f8211156118ee57600081815260208120601f850160051c81016020861015615dbb5750805b601f850160051c820191505b8181101561100457828155600101615dc7565b815167ffffffffffffffff811115615df457615df46155bc565b615e0881615e02845461577c565b84615d94565b602080601f831160018114615e3d5760008415615e255750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e6c57888601518255948401946001909101908401615e4d565b5085821015615e8a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615eac81846020870161543c565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564d58e94604d90293a1c1ad95bfe6a6e6c352c33c5774a4b6b4f4b6f7460da29c5a2646970667358221220dd0b851f900961e32e37a6ae5b5853db7ebab6f11c303fcce7b61d5ad4a86eea64736f6c63430008120033", + "solcInputHash": "a268142553104e6d2a73dbd3773cf551", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"newAPRUD7x3\",\"type\":\"uint16\"}],\"name\":\"APRChangeEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"id\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"enum LToken.Action\",\"name\":\"action\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountAfterFees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"enum LToken.Status\",\"name\":\"newStatus\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"newId\",\"type\":\"int256\"}],\"name\":\"ActivityEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balanceBefore\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"}],\"name\":\"MintedRewardsEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newTVL\",\"type\":\"uint256\"}],\"name\":\"TVLChangeEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"cancelWithdrawalRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositFor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feesRateUD7x3\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"frozenRequests\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fund\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAPR\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedRetained\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"getWithdrawnAmountAndFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"withdrawnAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalBlacklist\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalPause\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"globalOwner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"globalPause_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"globalBlacklist_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ldyStaking_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"instantWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"invested\",\"outputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ldyStaking\",\"outputs\":[{\"internalType\":\"contract LDYStaking\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"listenerContract\",\"type\":\"address\"}],\"name\":\"listenToTransfers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"processBigQueuedRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"processQueuedRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"realBalanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"realTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recoverUnderlying\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"repatriate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"requestWithdrawal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"retentionRateUD7x3\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"rewardsRedirectsFromTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"rewardsRedirectsToFrom\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"aprUD7x3\",\"type\":\"uint16\"}],\"name\":\"setAPR\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"feesRateUD7x3_\",\"type\":\"uint32\"}],\"name\":\"setFeesRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"fund_\",\"type\":\"address\"}],\"name\":\"setFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ldyStakingAddress\",\"type\":\"address\"}],\"name\":\"setLDYStaking\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"retentionRateUD7x3_\",\"type\":\"uint32\"}],\"name\":\"setRetentionRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawer_\",\"type\":\"address\"}],\"name\":\"setWithdrawer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"startRewardsRedirection\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"stopRewardsRedirection\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalQueued\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"transfersListeners\",\"outputs\":[{\"internalType\":\"contract ITransfersListener\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unclaimedFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"underlying\",\"outputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"listenerContract\",\"type\":\"address\"}],\"name\":\"unlistenToTransfers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unmintedRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"usableUnderlyings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"withdrawalQueue\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawalQueueCursor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawer\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:oz-upgrades-unsafe-allow\":\"external-library-linking\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Definitions: - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio). - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees). - Instant: Processed immediately. - Request: Queued for later processing. - Big Request: A requested withdrawal exceeding half of the retention rate. - (Withdrawal) queue: A list of all requested withdrawals sorted by priority. - Request ID: The index of a withdrawal request in the queue array. - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain. - Fees Rate: Percentage of fees applied to successful withdrawals. - Usable underlyings: Amount of underlying tokens that have been deposited through expected ways and are so considered safe to use by the contract. - Transfers listeners: External contracts listening on L-Tokens transfers. - Fund wallet: Wallet managed by the Ledgity's financial team. - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request processing. Note that words between parenthesis are sometimes omitted for brevity.Deployment notice: This contract can safely receive funds immediately after initialization. (i.e., there is no way for funds to be sent to non-owned addresses). It is, however, recommended to replace ASAP owner and fund wallets with multi-sig wallets.For further details, see \\\"LToken\\\" section of whitepaper.\",\"events\":{\"APRChangeEvent(uint16)\":{\"params\":{\"newAPRUD7x3\":\"The new APR in UD7x3 format.\"}},\"ActivityEvent(int256,address,uint8,uint256,uint256,uint8,int256)\":{\"params\":{\"account\":\"The account involved in the activity.\",\"action\":\"The type of activity.\",\"amount\":\"The amount of underlying tokens involved in the activity.\",\"id\":\"ID of the involved withdrawal request or NO_ID (-1) if not applicable.\",\"newId\":\"The new ID of the request if it has been moved in the queue.\",\"newStatus\":\"The new status of the activity.\"}},\"AdminChanged(address,address)\":{\"details\":\"Emitted when the admin account has changed.\"},\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"BeaconUpgraded(address)\":{\"details\":\"Emitted when the beacon is changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"MintedRewardsEvent(address,uint256,uint256)\":{\"params\":{\"account\":\"The account that received the rewards.\",\"balanceBefore\":\"The balance of the account before the minting.\",\"rewards\":\"The amount of minted rewards.\"}},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"TVLChangeEvent(uint256)\":{\"details\":\"TVL = realTotalSupply()\",\"params\":{\"newTVL\":\"The new TVL of the contract.\"}},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have not been yet minted to the specified account.\",\"params\":{\"account\":\"The account to check the total balance of.\"},\"returns\":{\"_0\":\"The total balance of the account.\"}},\"cancelWithdrawalRequest(uint256)\":{\"params\":{\"requestId\":\"The ID of the withdrawal request to cancel.\"}},\"decimals()\":{\"details\":\"The ERC20WrapperUpgradeable version is preferred because it mirrors the decimals amount of the underlying stablecoin token.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"deposit(uint256)\":{\"params\":{\"amount\":\"The amount of underlying tokens to deposit.\"}},\"depositFor(address,uint256)\":{\"details\":\"Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\"},\"getAPR()\":{\"returns\":{\"_0\":\"The current APR in UD7x3 format.\"}},\"getExpectedRetained()\":{\"returns\":{\"amount\":\"The expected amount of retained underlying tokens.\"}},\"getWithdrawnAmountAndFees(address,uint256)\":{\"params\":{\"account\":\"The account initiating the withdrawal.\",\"amount\":\"The amount of the withdrawal.\"}},\"globalBlacklist()\":{\"returns\":{\"_0\":\"The address of the GlobalBlacklist contract.\"}},\"globalOwner()\":{\"returns\":{\"_0\":\"The address of the GlobalOwner contract.\"}},\"globalPause()\":{\"returns\":{\"_0\":\"The address of the GlobalPause contract.\"}},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(address,address,address,address,address)\":{\"details\":\"See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\",\"params\":{\"globalBlacklist_\":\"The address of the GlobalBlacklist contract.\",\"globalOwner_\":\"The address of the GlobalOwner contract.\",\"globalPause_\":\"The address of the GlobalPause contract.\",\"underlyingToken\":\"The address of the underlying stablecoin ERC20 token.\"}},\"instantWithdrawal(uint256)\":{\"details\":\"In order to save some gas and time to users, frontends should propose this function to users only when it has been verified that it will not revert. They should propose the requestWithdrawal() function otherwise.\",\"params\":{\"amount\":\"The amount L-Tokens to withdraw.\"}},\"invested()\":{\"returns\":{\"_0\":\"The reference to the invested token contract.\"}},\"listenToTransfers(address)\":{\"details\":\"Each time a transfer occurs, the onLTokenTransfer() function of the specified contract will be called.IMPORTANT SECURITY NOTE: This method is not intended to be used with contracts that are not owned by the Ledgity team.\",\"params\":{\"listenerContract\":\"The address of the new transfers listener contract.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"returns\":{\"_0\":\"The address of the owner\"}},\"paused()\":{\"details\":\"Both version are the same as ERC20BaseUpgradeable.paused() mirrors GlobalPausableUpgradeable.paused(), so a random one is chosen.\",\"returns\":{\"_0\":\"Whether the contract is paused or not.\"}},\"processBigQueuedRequest(uint256)\":{\"details\":\"In contrast to non-big requests processing, this function will uses to fund wallet's balance to fill the request. This allows processing requests that are greater than retention rate without having to exceed this rate on the contract.\",\"params\":{\"requestId\":\"The ID of the big request to process.\"}},\"processQueuedRequests()\":{\"details\":\"For further details, see \\\"LToken > Withdrawals\\\" section of whitepaper.\"},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\"},\"realBalanceOf(address)\":{\"params\":{\"account\":\"The account to check the real balance of.\"},\"returns\":{\"_0\":\"The real balance of the account.\"}},\"realTotalSupply()\":{\"returns\":{\"_0\":\"The real total supply of L-Tokens.\"}},\"recoverERC20(address,uint256)\":{\"details\":\"This override of RecoverableUpgradeable.recoverERC20() prevents the recovered token from being the underlying token.\",\"params\":{\"amount\":\"The amount of token to recover.\",\"tokenAddress\":\"The address of the token to recover.\"}},\"recoverUnderlying()\":{\"details\":\"To prevent owner from being able to drain the contract, this function only allows recovering \\\"unusable\\\" underlying tokens, i.e., tokens that have not been sent through fund() or deposit() functions.\"},\"repatriate(uint256)\":{\"details\":\"The function will revert if repatriated amount makes the contract exceeding the retention rate.\",\"params\":{\"amount\":\"The amount of underlying tokens to repatriate.\"}},\"requestWithdrawal(uint256)\":{\"details\":\"The sender must attach 0.003 ETH to pre-pay the future processing gas fees paid by the withdrawer wallet.\",\"params\":{\"amount\":\"The amount L-Tokens to withdraw.\"}},\"setAPR(uint16)\":{\"params\":{\"aprUD7x3\":\"The new APR in UD7x3 format.\"}},\"setFeesRate(uint32)\":{\"params\":{\"feesRateUD7x3_\":\"The new withdrawal fee rate in UD7x3 format.\"}},\"setFund(address)\":{\"params\":{\"fund_\":\"The address of the new fund wallet.\"}},\"setLDYStaking(address)\":{\"params\":{\"ldyStakingAddress\":\"The address of the new LDYStaking contract.\"}},\"setRetentionRate(uint32)\":{\"details\":\"The retention rate is capped at 10%, which ensures that no more than 10% of deposited assets will ever be exposed in this contract (reduces attack surface).\",\"params\":{\"retentionRateUD7x3_\":\"The new retention rate in UD7x3 format.\"}},\"setWithdrawer(address)\":{\"params\":{\"withdrawer_\":\"The address of the new withdrawer wallet.\"}},\"startRewardsRedirection(address,address)\":{\"params\":{\"from\":\"The address of the account to redirect rewards from.\",\"to\":\"The address of the account to redirect rewards to.\"}},\"stopRewardsRedirection(address,address)\":{\"params\":{\"from\":\"The address of the account to stop redirecting rewards from.\",\"to\":\"The address of the account to stop redirecting rewards to.\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"returns\":{\"_0\":\"The total supply of L-Tokens.\"}},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"},\"underlying()\":{\"details\":\"Returns the address of the underlying ERC-20 token that is being wrapped.\"},\"unlistenToTransfers(address)\":{\"details\":\"The onLTokenTransfer() function of the specified contract will not be called anymore each time a L-Token transfer occurs.\",\"params\":{\"listenerContract\":\"The address of the listener contract.\"}},\"unmintedRewardsOf(address)\":{\"details\":\"This is a public implementation of InvestUpgradeable_rewardsOf(). In the context of LToken, this function returns the amount of rewards that have not been distributed/minted yet to the specified account.This is particularly useful for off-chain services to display charts and statistics, as seen in the Ledgity Yield's frontend.\",\"params\":{\"account\":\"The account to check the unminted rewards of.\"},\"returns\":{\"_0\":\"The amount of account's unminted rewards.\"}},\"upgradeTo(address)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"upgradeToAndCall(address,bytes)\":{\"custom:oz-upgrades-unsafe-allow-reachable\":\"delegatecall\",\"details\":\"Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call encoded in `data`. Calls {_authorizeUpgrade}. Emits an {Upgraded} event.\"},\"withdrawTo(address,uint256)\":{\"details\":\"Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\"}},\"stateVariables\":{\"frozenRequests\":{\"details\":\"If a request emitter as been blacklisted, its request is moved here to prevent it from blocking the queue.\"},\"transfersListeners\":{\"details\":\"onLTokenTransfer() functions of those contracts will be called on each transfer.\"},\"usableUnderlyings\":{\"details\":\"Are usable, only underlying tokens deposit through deposit() or fund() functions.\"}},\"title\":\"LToken\",\"version\":1},\"userdoc\":{\"events\":{\"APRChangeEvent(uint16)\":{\"notice\":\"Emitted to inform listeners about a change in the APR's value.\"},\"ActivityEvent(int256,address,uint8,uint256,uint256,uint8,int256)\":{\"notice\":\"Emitted to inform listerners about an activity related to deposits and withdrawals.\"},\"MintedRewardsEvent(address,uint256,uint256)\":{\"notice\":\"Emitted to inform listeners that some rewards have been minted.\"},\"TVLChangeEvent(uint256)\":{\"notice\":\"Emitted to inform listeners about a change in the contract's TVL.\"}},\"kind\":\"user\",\"methods\":{\"balanceOf(address)\":{\"notice\":\"Retrieves the total balance of L-Tokens that belong to the account.\"},\"cancelWithdrawalRequest(uint256)\":{\"notice\":\"Cancels a given withdrawal request. The request emitter receive back its L-Tokens and no fees will be charged.\"},\"claimFees()\":{\"notice\":\"Used by owner to claim fees generated from successful withdrawals.\"},\"decimals()\":{\"notice\":\"Required override of decimals() which is implemented by both ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\"},\"deposit(uint256)\":{\"notice\":\"Allows exchanging some underlying tokens for the same amount of L-Tokens.\"},\"depositFor(address,uint256)\":{\"notice\":\"Override of ERC20WrapperUpgradeable.depositFor() that reverts. Use deposit() function instead.\"},\"feesRateUD7x3()\":{\"notice\":\"Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\"},\"frozenRequests(uint256)\":{\"notice\":\"Holds a list of all currently frozen withdrawal requests.\"},\"fund()\":{\"notice\":\"Holds address of fund wallet (managed by Ledgity financial team).\"},\"getAPR()\":{\"notice\":\"Retrieves the most recently set APR.\"},\"getExpectedRetained()\":{\"notice\":\"Computes the maximum amount of underlying tokens that should be retained by the contract (based on retention rate).\"},\"getWithdrawnAmountAndFees(address,uint256)\":{\"notice\":\"Computes fees and net withdrawn amount for a given account withdrawing a given amount.\"},\"globalBlacklist()\":{\"notice\":\"Retrieves the address of GlobalBlacklist contract.\"},\"globalOwner()\":{\"notice\":\"Retrieves the address of GlobalOwner contract.\"},\"globalPause()\":{\"notice\":\"Retrieves the address of GlobalPause contract.\"},\"initialize(address,address,address,address,address)\":{\"notice\":\"Initializer function of the contract. It replaces the constructor() function in the context of upgradeable contracts.\"},\"instantWithdrawal(uint256)\":{\"notice\":\"Allows instaneously exchanging a given amount of L-Tokens for the same amount of underlying tokens. It will fail if the contract currently doesn't hold enough underlying tokens to cover the withdrawal.\"},\"invested()\":{\"notice\":\"Retrieves the reference to the invested token contract.\"},\"ldyStaking()\":{\"notice\":\"Holds a reference to the LDYStaking contract.\"},\"listenToTransfers(address)\":{\"notice\":\"Adds a new contract to the L-Token transfers list.\"},\"owner()\":{\"notice\":\"Override of OwnableUpgradeable.owner() that retrieves the owner's address from the GlobalOwner contract instead.\"},\"paused()\":{\"notice\":\"Required override of paused() which is implemented by both GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\"},\"processBigQueuedRequest(uint256)\":{\"notice\":\"Processes a given queued big withdrawal request (one that exceeds half of the retention rate).\"},\"processQueuedRequests()\":{\"notice\":\"Processes queued withdrawal requests until there is else no more requests, else not enough underlying tokens to continue.\"},\"realBalanceOf(address)\":{\"notice\":\"Retrieves the \\\"real\\\" balance of an account, i.e., excluding its not yet minted/distributed rewards.\"},\"realTotalSupply()\":{\"notice\":\"Returns the \\\"real\\\" amount of existing L-Tokens, i.e., excluding not yet minted withdrawal fees and L-Tokens currently in the withdrawal queue.\"},\"recoverERC20(address,uint256)\":{\"notice\":\"Recovers a specified amount of a given token address.\"},\"recoverUnderlying()\":{\"notice\":\"Recovers underlying tokens accidentally sent to the contract.\"},\"renounceOwnership()\":{\"notice\":\"Override of OwnableUpgradeable.renounceOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"repatriate(uint256)\":{\"notice\":\"Used by the fund wallet to repatriate underlying tokens on the contract whenever those are required to fulfill some withdrawal requests.\"},\"requestWithdrawal(uint256)\":{\"notice\":\"Allows requesting the exchange of a given amount of L-Tokens for the same amount of underlying tokens. The request will be automatically processed later.\"},\"retentionRateUD7x3()\":{\"notice\":\"Holds the retention rate in UD7x3 format.\"},\"rewardsRedirectsFromTo(address)\":{\"notice\":\"Holds active rewards redirections in both from->to and to->from[] ways.\"},\"setAPR(uint16)\":{\"notice\":\"Updates the investment APR. Restricted to owner.\"},\"setFeesRate(uint32)\":{\"notice\":\"Updates the current withdrawal fee rate.\"},\"setFund(address)\":{\"notice\":\"Updates the address of the fund wallet.\"},\"setLDYStaking(address)\":{\"notice\":\"Updates the address of LDYStaking contract.\"},\"setRetentionRate(uint32)\":{\"notice\":\"Updates the current underlying token retention rate.\"},\"setWithdrawer(address)\":{\"notice\":\"Updates the address of the withdrawer wallet.\"},\"startRewardsRedirection(address,address)\":{\"notice\":\"Enables redirection of rewards from one account to another.\"},\"stopRewardsRedirection(address,address)\":{\"notice\":\"Disable an active rewards redirection.\"},\"totalQueued()\":{\"notice\":\"Holds the amount of L-Tokens currently in the withdrawal queue.\"},\"totalSupply()\":{\"notice\":\"Retrives the total supply of L-Tokens, including not yet minted withdrawal fees and L-Tokens currently in the withdrawal queue.\"},\"transferOwnership(address)\":{\"notice\":\"Override of OwnableUpgradeable.transferOwnership() that always reverts. Ownership is managed by the GlobalOwner contract and must be modified there.\"},\"transfersListeners(uint256)\":{\"notice\":\"Holds a list of contracts' references that are listening to L-Tokens transfers.\"},\"unclaimedFees()\":{\"notice\":\"Holds the amount of withdrawal fees not yet claimed by contract's owner.\"},\"unlistenToTransfers(address)\":{\"notice\":\"Removes a contract from the L-Token transfers list.\"},\"unmintedRewardsOf(address)\":{\"notice\":\"Retrieves the amount of given account's not yet minted rewards.\"},\"usableUnderlyings()\":{\"notice\":\"Holds the amount of underlying tokens considered as usable by the contract.\"},\"withdrawTo(address,uint256)\":{\"notice\":\"Override of ERC20WrapperUpgradeable.withdrawTo() that reverts. Use instantWithdrawal() or requestWithdrawal() functions instead.\"},\"withdrawalQueue(uint256)\":{\"notice\":\"Holds an ordered list of active withdrawal requests.\"},\"withdrawalQueueCursor()\":{\"notice\":\"Holds the index of the next withdrawal request to process in the queue.\"},\"withdrawer()\":{\"notice\":\"Holds address of withdrawer wallet (managed by withdrawal server).\"}},\"notice\":\"Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e., investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin. As soon as a wallet holds some L-Tokens, it starts receiving rewards in the form of additional L-Tokens, which are auto-compounded over time.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/LToken.sol\":\"LToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0xd14a627157b9a411d2410713e5dd3a377e9064bd5c194a90748bbf27ea625784\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../security/PausableUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract unpausable.\\n */\\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\\n function __ERC20Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xf0bd7f71ffae5f0addd375e8511fbf2ad8ca0c9b2606c32d92bdda7d76a7a81c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../utils/SafeERC20Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of the ERC20 token contract to support token wrapping.\\n *\\n * Users can deposit and withdraw \\\"underlying tokens\\\" and receive a matching number of \\\"wrapped tokens\\\". This is useful\\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\\n * wrapping of an existing \\\"basic\\\" ERC20 into a governance token.\\n *\\n * _Available since v4.2._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\\n IERC20Upgradeable private _underlying;\\n\\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n __ERC20Wrapper_init_unchained(underlyingToken);\\n }\\n\\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n require(underlyingToken != this, \\\"ERC20Wrapper: cannot self wrap\\\");\\n _underlying = underlyingToken;\\n }\\n\\n /**\\n * @dev See {ERC20-decimals}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\\n return value;\\n } catch {\\n return super.decimals();\\n }\\n }\\n\\n /**\\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\\n */\\n function underlying() public view returns (IERC20Upgradeable) {\\n return _underlying;\\n }\\n\\n /**\\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\\n */\\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\\n address sender = _msgSender();\\n require(sender != address(this), \\\"ERC20Wrapper: wrapper can't deposit\\\");\\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\\n _mint(account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\\n */\\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\\n _burn(_msgSender(), amount);\\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\\n * function that can be exposed with access control if desired.\\n */\\n function _recover(address account) internal virtual returns (uint256) {\\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\\n _mint(account, value);\\n return value;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x14bb62a60fcbc911c33ac0e5456bf31ed50b502c30be46ee15bd3b698e91bd81\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\\n * 0 before setting it to a non-zero value.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x4dae161227d332808312ee2caf6384929321b83c16cc89b5642985fbec6b814c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This contract acts as a placeholder for the real LDYStaking contract until\\n * this one is deployed.\\n *\\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\\n * one the LToken contract relies on.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LDYStaking is Ownable2Step {\\n /**\\n * @notice Holds a mapping of addresses that default to the highest staking tier.\\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\\n */\\n mapping(address => bool) public highTierAccounts;\\n\\n /**\\n * @notice Update high tier status of a given account.\\n * @param account The account to update the high tier status of.\\n */\\n function setHighTierAccount(address account, bool status) public onlyOwner {\\n highTierAccounts[account] = status;\\n }\\n\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * elligible to any LDY staking tier, except if the account is in the\\n * highTierAccounts mapping.\\n * @param account The account to check the tier of.\\n */\\n function tierOf(address account) public view returns (uint256 tier) {\\n if (highTierAccounts[account]) return 3;\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x7be21f1a748fedb7b8b873230e24be45922e8bc09e87147b980a0a596e7550db\",\"license\":\"MIT\"},\"contracts/src/GlobalBlacklist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalBlacklist\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds a global mapping of blacklisted accounts shared by all contracts of the\\n * Ledgity Yield codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\\n * and getter functions to easily check against this global blacklist.\\n *\\n * @dev For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Mapping of accounts to their blacklist status.\\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\\n */\\n mapping(address => bool) private _list;\\n\\n /// @dev Emitted when `account` is blacklisted.\\n event Blacklisted(address account);\\n\\n /// @dev Emitted when `account` is unblacklisted.\\n event Unblacklisted(address account);\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Adds a given account to the blacklist.\\n * @param account The account's address to be blacklisted.\\n */\\n function blacklist(address account) external onlyOwner {\\n require(account != address(0), \\\"L20\\\");\\n _list[account] = true;\\n emit Blacklisted(account);\\n }\\n\\n /**\\n * @notice Removes a given account from the blacklist.\\n * @param account The account's address to be un-blacklisted.\\n */\\n function unBlacklist(address account) external onlyOwner {\\n _list[account] = false;\\n emit Unblacklisted(account);\\n }\\n\\n /**\\n * @notice Checks whether a given account is blacklisted.\\n * @param account Address of the account to check.\\n * @return 'true' if the account is blacklisted, 'false' otherwise\\n */\\n function isBlacklisted(address account) external view returns (bool) {\\n // Gas optimization: Avoid accessing storage if account is the zero address\\n // (e.g, during a mint or a burn of tokens)\\n if (account == address(0)) return false;\\n\\n // Else, return current account's blacklist status\\n return _list[account];\\n }\\n}\\n\",\"keccak256\":\"0x7e771076a06cfec935df22cf2d307df7e1f7df5b887976ec1dea30f8b68a878d\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xa3b880c4d82e796c162c99a398b569ce4a8e6d27232014b81a6a4503718f12dc\",\"license\":\"MIT\"},\"contracts/src/GlobalPause.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalPause\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Holds a global pause state shared by all contracts of the Ledgity Yield\\n * codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\\n * paused() function that retrieves the pause state from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalPause\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalPause is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n PausableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\\n * but restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n}\\n\",\"keccak256\":\"0x9a0767e761dbd1d5800db03558c3903f229e6ef29f5fe5ff38f45fb4d7572e2e\",\"license\":\"MIT\"},\"contracts/src/LToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n// Contracts\\nimport {ERC20WrapperUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\\\";\\nimport \\\"./abstracts/base/ERC20BaseUpgradeable.sol\\\";\\nimport {InvestUpgradeable} from \\\"./abstracts/InvestUpgradeable.sol\\\";\\nimport {LDYStaking} from \\\"./DummyLDYStaking.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {SUD} from \\\"./libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport {ITransfersListener} from \\\"./interfaces/ITransfersListener.sol\\\";\\n\\n/**\\n * @title LToken\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e.,\\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\\n * the form of additional L-Tokens, which are auto-compounded over time.\\n *\\n * @dev Definitions:\\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\\n * - Instant: Processed immediately.\\n * - Request: Queued for later processing.\\n * - Big Request: A requested withdrawal exceeding half of the retention rate.\\n * - (Withdrawal) queue: A list of all requested withdrawals sorted by priority.\\n * - Request ID: The index of a withdrawal request in the queue array.\\n * - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain.\\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\\n * expected ways and are so considered safe to use by the contract.\\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\\n * processing.\\n *\\n * Note that words between parenthesis are sometimes omitted for brevity.\\n *\\n * @dev Deployment notice:\\n * This contract can safely receive funds immediately after initialization. (i.e., there\\n * is no way for funds to be sent to non-owned addresses). It is, however, recommended to\\n * replace ASAP owner and fund wallets with multi-sig wallets.\\n *\\n * @dev For further details, see \\\"LToken\\\" section of whitepaper.\\n * @custom:oz-upgrades-unsafe-allow external-library-linking\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /// @dev Represents type of actions triggering ActivityEvent events.\\n enum Action {\\n Deposit,\\n Withdraw\\n }\\n\\n /// @dev Represents different status of actions triggering ActivityEvent events.\\n enum Status {\\n Queued,\\n Cancelled,\\n Success,\\n Moved\\n }\\n\\n /**\\n * @notice Represents a withdrawal request in the queue.\\n * @dev A request fits in a single storage slot (32 bytes).\\n * @param account The account that initiated the request.\\n * @param amount The amount of underlying tokens requested.\\n */\\n struct WithdrawalRequest {\\n address account; // 20 bytes\\n uint96 amount; // 12 bytes\\n }\\n\\n /// @notice Upper limit of retention rate.\\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\\n\\n /// @notice Upper limit of fees rate.\\n uint32 private constant MAX_FEES_RATE_UD7x3 = 20 * 10 ** 3; // 20%\\n\\n /// @notice Used in activity events to represent the absence of request ID.\\n int256 private constant NO_ID = -1;\\n\\n /// @notice Holds a reference to the LDYStaking contract.\\n LDYStaking public ldyStaking;\\n\\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\\n address payable public withdrawer;\\n\\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\\n address public fund;\\n\\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\\n uint32 public feesRateUD7x3;\\n\\n /// @notice Holds the retention rate in UD7x3 format.\\n uint32 public retentionRateUD7x3;\\n\\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\\n uint256 public unclaimedFees;\\n\\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\\n uint256 public totalQueued;\\n\\n /**\\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\\n */\\n uint256 public usableUnderlyings;\\n\\n /// @notice Holds an ordered list of active withdrawal requests.\\n WithdrawalRequest[] public withdrawalQueue;\\n\\n /// @notice Holds the index of the next withdrawal request to process in the queue.\\n uint256 public withdrawalQueueCursor;\\n\\n /**\\n * @notice Holds a list of all currently frozen withdrawal requests.\\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\\n * it from blocking the queue.\\n */\\n WithdrawalRequest[] public frozenRequests;\\n\\n /**\\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\\n */\\n ITransfersListener[] public transfersListeners;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the contract's TVL.\\n * @dev TVL = realTotalSupply()\\n * @param newTVL The new TVL of the contract.\\n */\\n event TVLChangeEvent(uint256 newTVL);\\n\\n /**\\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\\n * @param account The account involved in the activity.\\n * @param action The type of activity.\\n * @param amount The amount of underlying tokens involved in the activity.\\n * @param newStatus The new status of the activity.\\n * @param newId The new ID of the request if it has been moved in the queue.\\n */\\n event ActivityEvent(\\n int256 indexed id,\\n address indexed account,\\n Action indexed action,\\n uint256 amount,\\n uint256 amountAfterFees,\\n Status newStatus,\\n int256 newId\\n );\\n\\n /**\\n * @notice Emitted to inform listeners that some rewards have been minted.\\n * @param account The account that received the rewards.\\n * @param balanceBefore The balance of the account before the minting.\\n * @param rewards The amount of minted rewards.\\n */\\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\\n\\n /// @notice Reverts if the function caller is not the withdrawer wallet.\\n modifier onlyWithdrawer() {\\n require(_msgSender() == withdrawer, \\\"L39\\\");\\n _;\\n }\\n\\n /// @notice Reverts if the function caller is not the fund wallet.\\n modifier onlyFund() {\\n require(_msgSender() == fund, \\\"L40\\\");\\n _;\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\\n */\\n function initialize(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address ldyStaking_,\\n address underlyingToken\\n ) public initializer {\\n // Initialize ERC20 base.\\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\\n __ERC20Base_init(\\n globalOwner_,\\n globalPause_,\\n globalBlacklist_,\\n string(abi.encodePacked(\\\"Ledgity \\\", underlyingSymbol)),\\n string(abi.encodePacked(\\\"L\\\", underlyingSymbol))\\n );\\n\\n // IMPORTANT: Below calls must not be restricted to owner at any point.\\n // This is because the GlobalOwner contract may not be a fresh one, and so\\n // the contract deployer may not be the owner anymore after ERC20Base init.\\n\\n // Initialize other parents contracts.\\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\\n __Invest_init_unchained(address(this));\\n\\n // Set LDYStaking contract\\n ldyStaking = LDYStaking(ldyStaking_);\\n\\n // Set initial withdrawal fees rate to 0.3%\\n feesRateUD7x3 = 300;\\n\\n // Set initial retention rate to 10%\\n retentionRateUD7x3 = 10_000;\\n\\n // Default withdrawer and fund wallet to contract owner address. This prevents\\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\\n withdrawer = payable(owner());\\n fund = payable(owner());\\n }\\n\\n /**\\n * @notice Required override of decimals() which is implemented by both\\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\\n * decimals amount of the underlying stablecoin token.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function decimals()\\n public\\n view\\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\\n returns (uint8)\\n {\\n return ERC20WrapperUpgradeable.decimals();\\n }\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @notice Updates the current withdrawal fee rate.\\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\\n */\\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\\n require(feesRateUD7x3_ <= MAX_FEES_RATE_UD7x3, \\\"L88\\\");\\n feesRateUD7x3 = feesRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the current underlying token retention rate.\\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\\n * deposited assets will ever be exposed in this contract (reduces attack surface).\\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\\n */\\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \\\"L41\\\");\\n retentionRateUD7x3 = retentionRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the address of LDYStaking contract.\\n * @param ldyStakingAddress The address of the new LDYStaking contract.\\n */\\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\\n ldyStaking = LDYStaking(ldyStakingAddress);\\n }\\n\\n /**\\n * @notice Updates the address of the withdrawer wallet.\\n * @param withdrawer_ The address of the new withdrawer wallet.\\n */\\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\\n // Ensure address is not the zero address (pre-processing fees would be lost else)\\n require(withdrawer_ != address(0), \\\"L63\\\");\\n\\n // Set new withdrawer wallet's address\\n withdrawer = withdrawer_;\\n }\\n\\n /**\\n * @notice Updates the address of the fund wallet.\\n * @param fund_ The address of the new fund wallet.\\n */\\n function setFund(address payable fund_) public onlyOwner {\\n // Ensure address is not the zero address (deposited tokens would be lost else)\\n require(fund_ != address(0), \\\"L64\\\");\\n\\n // Set new fund wallet's address\\n fund = fund_;\\n }\\n\\n /**\\n * @notice Adds a new contract to the L-Token transfers list.\\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\\n * specified contract will be called.\\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\\n * contracts that are not owned by the Ledgity team.\\n * @param listenerContract The address of the new transfers listener contract.\\n */\\n function listenToTransfers(address listenerContract) public onlyOwner {\\n transfersListeners.push(ITransfersListener(listenerContract));\\n }\\n\\n /**\\n * @notice Removes a contract from the L-Token transfers list.\\n * @dev The onLTokenTransfer() function of the specified contract will not be called\\n * anymore each time a L-Token transfer occurs.\\n * @param listenerContract The address of the listener contract.\\n */\\n function unlistenToTransfers(address listenerContract) public onlyOwner {\\n // Find index of listener contract in transferListeners array\\n int256 index = -1;\\n uint256 transfersListenersLength = transfersListeners.length;\\n for (uint256 i = 0; i < transfersListenersLength; i++) {\\n if (address(transfersListeners[i]) == listenerContract) {\\n index = int256(i);\\n break;\\n }\\n }\\n\\n // Revert if given contract wasn't listening to transfers\\n require(index > -1, \\\"L42\\\");\\n\\n // Else, remove transfers listener contract from listeners array\\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\\n transfersListeners.pop();\\n }\\n\\n /**\\n * @notice Retrieves the amount of given account's not yet minted rewards.\\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\\n * context of LToken, this function returns the amount of rewards that have not been\\n * distributed/minted yet to the specified account.\\n * @dev This is particularly useful for off-chain services to display charts and\\n * statistics, as seen in the Ledgity Yield's frontend.\\n * @param account The account to check the unminted rewards of.\\n * @return The amount of account's unminted rewards.\\n */\\n function unmintedRewardsOf(address account) public view returns (uint256) {\\n return _rewardsOf(account, true);\\n }\\n\\n /**\\n * @notice Retrieves the \\\"real\\\" balance of an account, i.e., excluding its not yet\\n * minted/distributed rewards.\\n * @param account The account to check the real balance of.\\n * @return The real balance of the account.\\n */\\n function realBalanceOf(address account) public view returns (uint256) {\\n return super.balanceOf(account);\\n }\\n\\n /**\\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\\n * not been yet minted to the specified account.\\n * @param account The account to check the total balance of.\\n * @return The total balance of the account.\\n */\\n function balanceOf(address account) public view override returns (uint256) {\\n return realBalanceOf(account) + unmintedRewardsOf(account);\\n }\\n\\n /**\\n * @notice Returns the \\\"real\\\" amount of existing L-Tokens, i.e., excluding not yet\\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\\n * @return The real total supply of L-Tokens.\\n */\\n function realTotalSupply() public view returns (uint256) {\\n return super.totalSupply();\\n }\\n\\n /**\\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\\n * fees and L-Tokens currently in the withdrawal queue.\\n * @return The total supply of L-Tokens.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return realTotalSupply() + totalQueued + unclaimedFees;\\n }\\n\\n /**\\n * @notice Recovers a specified amount of a given token address.\\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\\n * token from being the underlying token.\\n * @inheritdoc RecoverableUpgradeable\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\\n // Ensure the token is not the underlying token\\n require(tokenAddress != address(underlying()), \\\"L43\\\");\\n\\n // Proceed to recovery\\n super.recoverERC20(tokenAddress, amount);\\n }\\n\\n /**\\n * @notice Recovers underlying tokens accidentally sent to the contract.\\n * @dev To prevent owner from being able to drain the contract, this function only\\n * allows recovering \\\"unusable\\\" underlying tokens, i.e., tokens that have not been\\n * sent through fund() or deposit() functions.\\n */\\n function recoverUnderlying() external onlyOwner {\\n // Compute the recoverable amount by taking the difference between the contract's\\n // balance and the amount of usable underlying tokens\\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\\n\\n // Revert if there is nothing to recover\\n require(recoverableAmount > 0, \\\"L44\\\");\\n\\n // Else, proceed to underlying tokens recovery\\n super.recoverERC20(address(underlying()), recoverableAmount);\\n }\\n\\n /**\\n * @notice Retrieves the amount of underlying tokens invested by the given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\\n * LToken contract, the investment of an account is equal to its real balance.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _investmentOf(address account) internal view override returns (uint256) {\\n return realBalanceOf(account);\\n }\\n\\n /**\\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract so\\n * it can distribute rewards to accounts before each period reset.\\n * @dev InvestUpgradeable contract already ensure that amount > 0.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\\n // Inform listeners of the rewards minting\\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\\n\\n // Mint L-Tokens rewards to account\\n _mint(account, amount);\\n\\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\\n return true;\\n }\\n\\n /**\\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\\n * called each time an account's balance is going to change.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\\n * @inheritdoc ERC20BaseUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\\n\\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\\n if (from != address(0)) _beforeInvestmentChange(from, true);\\n if (to != address(0)) _beforeInvestmentChange(to, true);\\n }\\n\\n /**\\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\\n * transfers listeners.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already checked in _beforeTokenTransfer().\\n * @inheritdoc ERC20Upgradeable\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n // If some L-Token have been burned/minted, inform listeners of a TVL change\\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\\n\\n // Trigger onLTokenTransfer() functions of all the transfers listeners\\n for (uint256 i = 0; i < transfersListeners.length; i++) {\\n transfersListeners[i].onLTokenTransfer(from, to, amount);\\n }\\n }\\n\\n /**\\n * @notice Computes the maximum amount of underlying tokens that should be retained\\n * by the contract (based on retention rate).\\n * @return amount The expected amount of retained underlying tokens.\\n */\\n function getExpectedRetained() public view returns (uint256 amount) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert totalSupply and retentionRate to SUD\\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\\n\\n // Compute and return expected retained amount\\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(expectedRetainedSUD, d);\\n }\\n\\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\\n function _transferExceedingToFund() internal {\\n // Retrieve the expected amount retained\\n uint256 expectedRetained = getExpectedRetained();\\n\\n // If usable underlyings are less than or equal to expected retained, return\\n if (usableUnderlyings <= expectedRetained) return;\\n\\n // Else, exceeding amount is equal to difference between those values\\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= exceedingAmount;\\n\\n // Transfer the exceeding amount to the fund wallet\\n underlying().safeTransfer(fund, exceedingAmount);\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L45\\\");\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\\n * Use deposit() function instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L46\\\");\\n }\\n\\n /**\\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\\n * @param amount The amount of underlying tokens to deposit.\\n */\\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough underlying tokens to deposit\\n require(underlying().balanceOf(_msgSender()) >= amount, \\\"L47\\\");\\n\\n // Update usable underlyings balance accordingly\\n usableUnderlyings += amount;\\n\\n // Inform listeners of the deposit activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Deposit,\\n amount,\\n amount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\\n super.depositFor(_msgSender(), amount);\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\\n * given amount.\\n * @param account The account initiating the withdrawal.\\n * @param amount The amount of the withdrawal.\\n */\\n function getWithdrawnAmountAndFees(\\n address account,\\n uint256 amount\\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\\n // If the account is eligible to staking tier 2, no fees are applied\\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\\n\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert amount and fees rate to SUD\\n uint256 amountSUD = SUD.fromAmount(amount, d);\\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\\n\\n // Compute fees and withdrawn amount (initial amount minus fees)\\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\\n fees = SUD.toAmount(feesSUD, d);\\n withdrawnAmount = amount - fees;\\n }\\n\\n /**\\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\\n * enough underlying tokens to cover the withdrawal.\\n * @dev In order to save some gas and time to users, frontends should propose this\\n * function to users only when it has been verified that it will not revert. They\\n * should propose the requestWithdrawal() function otherwise.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L48\\\");\\n\\n // Can the contract cover this withdrawal plus all already queued requests?\\n bool cond1 = totalQueued + amount <= usableUnderlyings;\\n\\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\\n\\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\\n if (!(cond1 || cond2)) revert(\\\"L49\\\");\\n\\n // Else, retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\\n\\n // Increase unclaimed fees amount accordingly\\n unclaimedFees += fees;\\n\\n // Decrease usable underlyings balance accordingly\\n usableUnderlyings -= withdrawnAmount;\\n\\n // Inform listeners of this instant withdrawal activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Burn withdrawal fees from the account\\n _burn(_msgSender(), fees);\\n\\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\\n super.withdrawTo(_msgSender(), withdrawnAmount);\\n }\\n\\n /**\\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\\n * amount of underlying tokens. The request will be automatically processed later.\\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\\n * paid by the withdrawer wallet.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function requestWithdrawal(\\n uint256 amount\\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L53\\\");\\n\\n // Ensure the requested amount doesn't overflow uint96\\n require(amount <= type(uint96).max, \\\"L54\\\");\\n\\n // Ensure the sender attached the pre-paid processing gas fees\\n require(msg.value == 0.003 * 10 ** 18, \\\"L55\\\");\\n\\n // Create withdrawal request data\\n WithdrawalRequest memory request = WithdrawalRequest({\\n account: _msgSender(),\\n amount: uint96(amount)\\n });\\n\\n // Will hold the request ID\\n uint256 requestId;\\n\\n // Append request to the withdrawal queue:\\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\\n withdrawalQueueCursor--;\\n requestId = withdrawalQueueCursor;\\n withdrawalQueue[requestId] = request;\\n }\\n // - At the end else\\n else {\\n withdrawalQueue.push(request);\\n requestId = withdrawalQueue.length - 1;\\n }\\n\\n // Increase total amount queued accordingly\\n totalQueued += amount;\\n\\n // Inform listeners of this new queued withdrawal activity event\\n emit ActivityEvent(\\n int256(requestId),\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n amount,\\n Status.Queued,\\n NO_ID\\n );\\n\\n // Burn withdrawal L-Tokens amount from account's balance\\n _burn(_msgSender(), amount);\\n\\n // Forward pre-paid processing gas fees to the withdrawer wallet\\n (bool sent, ) = withdrawer.call{value: msg.value}(\\\"\\\");\\n require(sent, \\\"L56\\\");\\n }\\n\\n /**\\n * @notice Processes queued withdrawal requests until there is else no more requests,\\n * else not enough underlying tokens to continue.\\n * @dev For further details, see \\\"LToken > Withdrawals\\\" section of whitepaper.\\n */\\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\\n // Accumulators variables, will be written on-chain after the loop\\n uint256 cumulatedFees = 0;\\n uint256 cumulatedWithdrawnAmount = 0;\\n uint256 nextRequestId = withdrawalQueueCursor;\\n\\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\\n // requests are increasing the queue length when moved at the end of the queue.\\n uint256 queueLength = withdrawalQueue.length;\\n\\n // Iterate over requests to be processed\\n while (nextRequestId < queueLength) {\\n // Stop processing requests if there is not enough gas left to continue the\\n // loop and properly end the function call. This prevents an attacker from\\n // blocking the withdrawal processing by creating a ton of tiny requests so\\n // this function call cannot fit anymore in block gas limit.\\n if (gasleft() < 45000) break;\\n\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\\n\\n // Skip empty request (processed big requests or cancelled requests)\\n if (request.account == address(0)) {}\\n //\\n // If account has been blacklisted since request emission\\n else if (isBlacklisted(request.account)) {\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request in the frozen requests list\\n frozenRequests.push(request);\\n }\\n //\\n // Or if request is a big request, move it at the end of the queue for now.\\n // This request will be processed manually later using processBigQueuedRequest()\\n else if (request.amount > getExpectedRetained() / 2) {\\n // Inform listeners of this queued request being moved at the end of the queue\\n emit ActivityEvent(\\n int256(nextRequestId),\\n _msgSender(),\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Moved,\\n int256(withdrawalQueue.length)\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request at the end of the queue\\n withdrawalQueue.push(request);\\n }\\n //\\n // Else, continue request processing\\n else {\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Break if the contract doesn't hold enough funds to cover the request\\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\\n\\n // Accumulate fees and withdrawn amount\\n cumulatedFees += fees;\\n cumulatedWithdrawnAmount += withdrawnAmount;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(nextRequestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Transfer underlying tokens to account. Burning L-Tokens is not required\\n // as equestWithdrawal() already did it.\\n // Security note: Re-entrancy warning are disabled as the request has\\n // just been deleted from the queue, it will so be skipped if trying to\\n // process it again.\\n // slither-disable-next-line reentrancy-no-eth\\n underlying().safeTransfer(request.account, withdrawnAmount);\\n }\\n\\n // Increment next request ID\\n nextRequestId++;\\n }\\n\\n // Increase unclaimed fees by the amount of cumulated fees\\n unclaimedFees += cumulatedFees;\\n\\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\\n usableUnderlyings -= cumulatedWithdrawnAmount;\\n\\n // Decrease total amount queued by the cumulated amount requested\\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\\n\\n // Update new queue cursor\\n withdrawalQueueCursor = nextRequestId;\\n\\n // Retention rate cannot exceeds as the withdrawal decreases both usable\\n // underlyings and expected retained amounts by the same number and as the\\n // expected retained amount is a subset of usable underlyings amount.\\n }\\n\\n /**\\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\\n * the retention rate).\\n * @dev In contrast to non-big requests processing, this function will uses to fund\\n * wallet's balance to fill the request. This allows processing requests that are\\n * greater than retention rate without having to exceed this rate on the contract.\\n * @param requestId The ID of the big request to process.\\n */\\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure the request is active\\n require(request.account != address(0), \\\"L66\\\");\\n\\n // Ensure the request emitter has not been blacklisted since request emission\\n require(!isBlacklisted(request.account), \\\"L50\\\");\\n\\n // Ensure this is indeed a big request\\n require(request.amount > getExpectedRetained() / 2, \\\"L51\\\");\\n\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\\n uint256 fundBalance = underlying().balanceOf(fund);\\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \\\"L52\\\");\\n\\n // Increase amount of unclaimed fees accordingly\\n unclaimedFees += fees;\\n\\n // Decrease total queued amount by request amount\\n totalQueued -= request.amount;\\n\\n // Increment queue cursor if request was the next request to be processed\\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[requestId];\\n\\n // If fund wallet's balance can cover request, rely on it only\\n if (withdrawnAmount <= fundBalance) {\\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\\n }\\n // Else, cover request from both fund wallet and contract balances\\n else {\\n // Compute amount missing from fund wallet to cover request\\n uint256 missingAmount = withdrawnAmount - fundBalance;\\n\\n // Decrease usable amount of underlying tokens accordingly\\n usableUnderlyings -= missingAmount;\\n\\n // Transfer entire fund balance to request's emitter\\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\\n\\n // Transfer missing amount from contract balance to request emitter\\n underlying().safeTransfer(request.account, missingAmount);\\n }\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Cancels a given withdrawal request. The request emitter receive back its\\n * L-Tokens and no fees will be charged.\\n * @param requestId The ID of the withdrawal request to cancel.\\n */\\n function cancelWithdrawalRequest(\\n uint256 requestId\\n ) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure request belongs to caller\\n require(_msgSender() == request.account, \\\"L57\\\");\\n\\n // Decrease total amount queued accordingly\\n totalQueued -= request.amount;\\n\\n // Delete the withdrawal request from queue\\n delete withdrawalQueue[requestId];\\n\\n // Inform listeners of this cancelled withdrawal request activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Cancelled,\\n NO_ID\\n );\\n\\n // Mint back L-Tokens to account\\n _mint(request.account, uint256(request.amount));\\n }\\n\\n /**\\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\\n * whenever those are required to fulfill some withdrawal requests.\\n * @dev The function will revert if repatriated amount makes the contract exceeding\\n * the retention rate.\\n * @param amount The amount of underlying tokens to repatriate.\\n */\\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\\n // Ensure the fund wallet has enough funds to repatriate\\n require(amount <= underlying().balanceOf(fund), \\\"L58\\\");\\n\\n // Calculate new contract usable balance\\n uint256 newBalance = usableUnderlyings + amount;\\n\\n // Ensure the new balance doesn't exceed the retention rate\\n require(newBalance <= getExpectedRetained(), \\\"L59\\\");\\n\\n // Increase usable underlyings amount by repatriated amount\\n usableUnderlyings += amount;\\n\\n // Transfer amount from fund wallet to contract\\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\\n }\\n\\n /// @notice Used by owner to claim fees generated from successful withdrawals.\\n function claimFees() external onlyOwner {\\n // Ensure there are some fees to claim\\n require(unclaimedFees > 0, \\\"L60\\\");\\n\\n // Ensure the contract holds enough underlying tokens to cover fees\\n require(usableUnderlyings >= unclaimedFees, \\\"L61\\\");\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= unclaimedFees;\\n\\n // Store fees amount in memory and reset unclaimed fees amount\\n uint256 fees = unclaimedFees;\\n unclaimedFees = 0;\\n\\n // Transfer unclaimed fees to owner\\n underlying().safeTransfer(owner(), fees);\\n }\\n}\\n\",\"keccak256\":\"0x60644fd9d32b09ccadb2a138a53cbbca7aa12b312a3b5bcaec8579a1a5a49972\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure:\\n * The _globalOwner state must be set at initialization time and, for evident security\\n * reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9203f7a2a19def126d8ff0fde8357053ffcf1100d65ec8faec8299b6ed2c0c5a\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalPausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalPause} from \\\"../GlobalPause.sol\\\";\\n\\n/**\\n * @title GlobalPausableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit a pause state from the specified GlobalPause\\n * contract (see GlobalPause.sol). This design facilitates centralized management of\\n * pause state for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure\\n * The _globalPause state must be set at initialization time and, for evident security\\n * reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalPausableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\\n /**\\n * @notice The GlobalPause contract the pause state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalPause private _globalPause;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalPause_ The address of the GlobalPause contract.\\n */\\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n }\\n\\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\\n _globalPause = GlobalPause(globalPause_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalPause contract.\\n * @return The address of the GlobalPause contract.\\n */\\n function globalPause() public view returns (address) {\\n return address(_globalPause);\\n }\\n\\n /**\\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\\n * from the GlobalPause contract instead.\\n * @return Whether the contract is paused or not.\\n */\\n function paused() public view virtual override returns (bool) {\\n return _globalPause.paused();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xff508c0b8c48916885453b4894d0401e94580fb24fb6af1885a3e160864cde94\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalRestrictableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalBlacklist} from \\\"../GlobalBlacklist.sol\\\";\\n\\n/**\\n * @title GlobalRestrictableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit a blacklist state from the specified\\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\\n * centralized management of a blacklist for all the Ledgity Yield contracts.\\n *\\n * @dev Security measure:\\n * The _globalBlacklist state must be set at initialization time and, for evident\\n * security reasons, cannot be changed afterward.\\n *\\n * @dev For further details, see \\\"GlobalRestrictableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalRestrictableUpgradeable is Initializable {\\n /**\\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalBlacklist private _globalBlacklist;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n }\\n\\n function __GlobalRestrictable_init_unchained(\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalBlacklist contract.\\n * @return The address of the GlobalBlacklist contract.\\n */\\n function globalBlacklist() public view returns (address) {\\n return address(_globalBlacklist);\\n }\\n\\n /**\\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n */\\n modifier notBlacklisted(address account) {\\n require(isBlacklisted(account) == false, \\\"L9\\\");\\n _;\\n }\\n\\n /**\\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n * @return Whether the account is blacklisted.\\n */\\n function isBlacklisted(address account) internal view returns (bool) {\\n return _globalBlacklist.isBlacklisted(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0032fde90d9cf23e70dd4b604ae0d1ed3283f117bc24f68d32f8933e1bd372bc\",\"license\":\"MIT\"},\"contracts/src/abstracts/InvestUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n// Contracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"./GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"./GlobalRestrictableUpgradeable.sol\\\";\\nimport \\\"./base/BaseUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../abstracts/RecoverableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {APRHistory as APRH} from \\\"../libs/APRHistory.sol\\\";\\nimport {SUD} from \\\"../libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title InvestUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with utilities to manage an invested token,\\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\\n *\\n * @dev Intuition:\\n * This contract primarily exists for code splitting and reusability. It unburdens the\\n * LToken contract code, making it easier to understand and maintain.\\n *\\n * This contract is generic because it may be used in the LDYStaking contract in the future.\\n *\\n * @dev Definitions:\\n * - Investment: The act of depositing or investing tokens into the contract.\\n * - Investment period: Time between the last invested amount change and the present.\\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\\n * distributed between investment periods.\\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\\n *\\n * @dev Derived contract must:\\n * - Set invested token during initialization\\n * - Implement _investmentOf() function\\n * - (optionally) Implement _distributeRewards() function\\n *\\n * @dev For further details, see \\\"InvestmentUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract InvestUpgradeable is BaseUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using APRH for APRH.Pack[];\\n\\n /**\\n * @notice Represents an account's investment period.\\n * @param timestamp The timestamp of the most recent rewards distribution.\\n * @param ref The reference of the last APR checkpoint at that timestamp.\\n */\\n struct InvestmentPeriod {\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n APRH.Reference ref;\\n }\\n\\n /**\\n * @notice Represents the investment details of an account.\\n * @param period The current investment period of the account.\\n * @param virtualBalance May hold a part of account rewards until they are claimed.\\n */\\n struct AccountDetails {\\n InvestmentPeriod period;\\n uint256 virtualBalance;\\n }\\n\\n /// @notice Holds a reference to the invested token's contract.\\n IERC20Upgradeable private _invested;\\n\\n /// @notice Holds investment details of each account.\\n mapping(address => AccountDetails) internal accountsDetails;\\n\\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\\n APRH.Pack[] private _aprHistory;\\n\\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\\n mapping(address => address) public rewardsRedirectsFromTo;\\n mapping(address => address[]) public rewardsRedirectsToFrom;\\n\\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\\n bool private _isClaiming;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the APR's value.\\n * @param newAPRUD7x3 The new APR in UD7x3 format.\\n */\\n event APRChangeEvent(uint16 newAPRUD7x3);\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param invested_ The address of the invested token contract.\\n */\\n function __Invest_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address invested_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __Invest_init_unchained(invested_);\\n }\\n\\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\\n // Set invested token\\n _invested = IERC20Upgradeable(invested_);\\n\\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\\n // of an empty APR history\\n _aprHistory.setAPR(0);\\n }\\n\\n /**\\n * @notice Retrieves the reference to the invested token contract.\\n * @return The reference to the invested token contract.\\n */\\n function invested() public view returns (IERC20Upgradeable) {\\n return _invested;\\n }\\n\\n /**\\n * @notice Updates the investment APR. Restricted to owner.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(uint16 aprUD7x3) public onlyOwner {\\n _aprHistory.setAPR(aprUD7x3);\\n emit APRChangeEvent(aprUD7x3);\\n }\\n\\n /**\\n * @notice Retrieves the most recently set APR.\\n * @return The current APR in UD7x3 format.\\n */\\n function getAPR() public view returns (uint16) {\\n return _aprHistory.getAPR();\\n }\\n\\n /**\\n * @notice Enables redirection of rewards from one account to another.\\n * @param from The address of the account to redirect rewards from.\\n * @param to The address of the account to redirect rewards to.\\n */\\n function startRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure the address is not already redirecting rewards\\n require(rewardsRedirectsFromTo[from] == address(0), \\\"L62\\\");\\n\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L12\\\");\\n require(to != address(0), \\\"L13\\\");\\n\\n // Ensure 'from' and 'to' addresses are distinct\\n require(from != to, \\\"L14\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L15\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Activate rewards redirection\\n rewardsRedirectsFromTo[from] = to;\\n rewardsRedirectsToFrom[to].push(from);\\n }\\n\\n /**\\n * @notice Disable an active rewards redirection.\\n * @param from The address of the account to stop redirecting rewards from.\\n * @param to The address of the account to stop redirecting rewards to.\\n */\\n function stopRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L16\\\");\\n require(to != address(0), \\\"L17\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L18\\\");\\n\\n // Ensure a rewards redirection was active\\n require(rewardsRedirectsFromTo[from] == to, \\\"L19\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Retrieve 'from' index in the redirection array of 'to'\\n int256 fromIndex = -1;\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\\n if (rewardsRedirectsToFrom[to][i] == from) {\\n fromIndex = int256(i);\\n break;\\n }\\n }\\n\\n // fromIndex should never be -1 at this point\\n assert(fromIndex >= 0);\\n\\n // Deactivate rewards redirection\\n rewardsRedirectsFromTo[from] = address(0);\\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\\n rewardsRedirectsToFrom[to].length - 1\\n ];\\n rewardsRedirectsToFrom[to].pop();\\n }\\n\\n /**\\n * @notice Retrieves the total amount of tokens invested by the given account.\\n * @dev Derived contracts must implement this function.\\n * @param account The account to get the investment of.\\n * @return The total amount of tokens invested by the given account.\\n */\\n function _investmentOf(address account) internal view virtual returns (uint256);\\n\\n /**\\n * @notice Distributes a specified amount of rewards to a given account.\\n * @dev Derived contracts may optionally implement this function.\\n * @dev Implementations must return true to indicate a successful distribution, and\\n * false otherwise. If it returns false, the rewards will be added to the account's\\n * virtual balance, in order to be claimed later.\\n * @param account The account to claim the rewards of.\\n * @param amount The amount of rewards to claim.\\n * @return Whether the rewards distribution was successfull.\\n */\\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\\n account; // Silence unused variables warning\\n amount;\\n return false;\\n }\\n\\n /**\\n * @notice Computes the rewards accrued over a specified period of time, based on a\\n * given APR and amount of invested tokens.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param beginTimestamp The moment the period commenced.\\n * @param endTimestamp The moment the period concluded.\\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\\n * @param investedAmount The amount of tokens deposited/invested during the period.\\n * @return The amount of rewards generated during the period.\\n */\\n function _calculatePeriodRewards(\\n uint40 beginTimestamp,\\n uint40 endTimestamp,\\n uint16 aprUD7x3,\\n uint256 investedAmount\\n ) internal view returns (uint256) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Compute the number of elapsed years\\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\\n\\n // Compute the growth in invested amount (thanks to rewards)\\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\\n\\n // Compute and return the rewards\\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(rewardsSUD, d);\\n }\\n\\n /**\\n * @notice Computes the sum of given account's invested amount, plus invested amount\\n * of all accounts that recursively redirect rewards to this account.\\n * @param account The account to calculate the deep investment of.\\n * @return deepInvestedAmount The deep invested amount.\\n */\\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\\n // Consider account's direct investment\\n deepInvestedAmount += _investmentOf(account);\\n\\n // But also the deep investments of all accounts redirecting rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param account The account to calculate the unclaimed rewards of.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\\n */\\n function _rewardsOf(\\n address account,\\n bool autocompound\\n ) internal view returns (uint256 rewards) {\\n // Retrieve account's investment details\\n AccountDetails memory details = accountsDetails[account];\\n\\n // Retrieve account's deep invested amount\\n uint256 investedAmount = _deepInvestmentOf(account);\\n\\n // Return 0 if the account has never invested or has no invested amount\\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\\n\\n // Retrieve reference and data of APR checkpoint at which started investment period\\n APRH.Reference memory currRef = details.period.ref;\\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\\n\\n // Retrieve reference of latest APR checkpoint\\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\\n\\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\\n // See \\\"InvestUpgradeable > Yield calculation > 1)\\\" section of the whitepaper\\n rewards = details.virtualBalance;\\n\\n // If start checkpoint is not the latest one\\n if (!APRH.eq(currRef, latestRef)) {\\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // 2) Calculate rewards from investment period start to next checkpoint\\n // See \\\"InvestUpgradeable > Yield calculation > 2)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n\\n // 3) Calculate rewards for each crossed pair of checkpoints\\n // See \\\"InvestUpgradeable > Yield calculation > 3)\\\" section of the whitepaper\\n while (true) {\\n // Set next checkpoint as the current one\\n currRef = nextRef;\\n currCheckpoint = nextCheckpoint;\\n\\n // Break if current checkpoint is the latest one\\n if (APRH.eq(currRef, latestRef)) break;\\n\\n // Else, retrieve the new next checkpoint\\n nextRef = APRH.incrementReference(currRef);\\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // Calculate rewards between the current pair of checkpoints\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n\\n // 4) Calculate rewards from the latest checkpoint to now\\n // See \\\"InvestUpgradeable > Yield calculation > 4)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n } else {\\n // 2.bis) Calculate rewards from investment period start to now\\n // See \\\"InvestUpgradeable > Yield calculation > 2.bis)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n }\\n\\n /**\\n * @notice Recursively resets the investment period of the specified account and of\\n * all accounts that directly or indirectly redirect rewards to this account.\\n * @param account The account to deeply reset the investment period of.\\n */\\n function _deepResetInvestmentPeriodOf(address account) internal {\\n // Reset account investment period timestamp and APR checkpoint to latest ones\\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\\n\\n // Also reset the ones of all accounts that recursively redirect rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Hook to be invoked before the invested amount of an account changes. It\\n * ensures that rewards are distributed and that account's investment period is reset.\\n * @param account The account whose invested amount is going to change.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n */\\n function _beforeInvestmentChange(address account, bool autocompound) internal {\\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\\n // minted in LToken._distributeRewards(), this guards against infinite loop.\\n if (_isClaiming) return;\\n\\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\\n // As first call will treat both addresses, the second call would be redundant.\\n // Therefore, we skip accounts already processed in this block to save up some gas.\\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\\n\\n // If account redirects its rewards\\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\\n if (redirectRewardsTo != address(0)) {\\n // Call hook on redirection target (this will indirectly reset the investment\\n // of this source account) and return\\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\\n return;\\n }\\n\\n // Else, compute account's undistributed/unclaimed rewards\\n uint256 rewards = _rewardsOf(account, autocompound);\\n\\n // If there are some rewards\\n if (rewards > 0) {\\n // Try to distribute rewards to account\\n _isClaiming = true;\\n bool distributed = _distributeRewards(account, rewards);\\n _isClaiming = false;\\n\\n // If rewards have not been distributed, accumulate them in account's virtual balance\\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\\n }\\n\\n // Finally, deeply reset investment period of the account\\n _deepResetInvestmentPeriodOf(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xdb6d0b0e2f2546b6be0ac9244e99017c5e5da1e5b7783d6fff50f4217b9ec820\",\"license\":\"MIT\"},\"contracts/src/abstracts/RecoverableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n// Conracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @title RecoverableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with helper functions allowing the recovery of\\n * assets accidentally sent to them.\\n *\\n * @dev Where are utilities Ether, ERC721, etc.?\\n * This abstract contract currently supports only ERC20 tokens. Derived contracts\\n * in this codebase currently do not implement the necessary functions to receive Ether\\n * or ERC721/ERC1155 tokens, so no recovery functions are provided for these assets.\\n *\\n * @dev For further details, see \\\"RecoverableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init(globalOwner_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Recoverable_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Recovers a specified amount of a given token address. Will fail if the\\n * contract doesn't hold enough tokens.\\n * @param tokenAddress The address of the token to recover.\\n * @param amount The amount of token to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\\n // Ensure the specified amount is not zero\\n require(amount > 0, \\\"L10\\\");\\n\\n // Create a reference to token's contract\\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\\n\\n // Ensure there is enough token to recover\\n require(tokenContract.balanceOf(address(this)) >= amount, \\\"L11\\\");\\n\\n // Transfer the recovered token amount to the sender\\n tokenContract.safeTransfer(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xc70110d1284c9e4aa7c518b3b98682dd9edbe6f6fb23761d825554ba41a80d5e\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"../GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"../GlobalRestrictableUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../RecoverableUpgradeable.sol\\\";\\n\\n/**\\n * @title BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contract acts as a base for numerous contracts in this codebase,\\n * minimizing code repetition and enhancing readability and maintainability.\\n *\\n * @dev For further details, see \\\"Base\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract BaseUpgradeable is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n GlobalPausableUpgradeable,\\n GlobalRestrictableUpgradeable,\\n RecoverableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n __UUPSUpgradeable_init();\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xe445c759682f31d39e63663ff8217072c0e81086bda11ea473247be334c3e424\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/ERC20BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\\\";\\nimport {ERC20PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport \\\"./BaseUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\n\\n/**\\n * @title ERC20BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contract is an extension of BaseUpgradeable intended to be used\\n * as a base for ERC20 tokens contracts.\\n *\\n * @dev For further details, see \\\"ERC20BaseUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract ERC20BaseUpgradeable is\\n ERC20Upgradeable,\\n BaseUpgradeable,\\n ERC20PausableUpgradeable\\n{\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param name_ The display name of the token.\\n * @param symbol_ The symbol of the token.\\n */\\n function __ERC20Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n string memory name_,\\n string memory symbol_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __ERC20_init(name_, symbol_);\\n __ERC20Pausable_init_unchained();\\n }\\n\\n function __ERC20Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\\n * state from the GlobalPause contract.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, PausableUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\\n * The ERC20PausableUpgradeable version is preferred because it also checks that\\n * the contract is not paused before allowing the transfer.\\n * @inheritdoc ERC20PausableUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n )\\n internal\\n virtual\\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\\n whenNotPaused\\n notBlacklisted(from)\\n notBlacklisted(to)\\n {\\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xa69b9acca2902fcfe513889516fcffc830903fc3c6a3a11e2ad8da7460201378\",\"license\":\"MIT\"},\"contracts/src/interfaces/ITransfersListener.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\ninterface ITransfersListener {\\n function onLTokenTransfer(address from, address to, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0xf1d4172da97ccaf7199601dd9bdb2ac92a49b6977ec34bba010af37f662549fb\",\"license\":\"MIT\"},\"contracts/src/libs/APRHistory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/**\\n * @title APRHistory\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This library offers utilities to efficiently maintain the history of an\\n * on-chain APR (Annual Percentage Rate) state. Each entry in this history is called\\n * a \\\"checkpoint\\\".\\n *\\n * @dev Intuition:\\n * Each checkpoint in an APR history consists of two data:\\n * - the creation timestamp\\n * - the APR at that time\\n *\\n * Given that reading and writing to storage slots are among the most costly operations\\n * in Solidity, this library provides a way to store those data in a way that minimizes\\n * the number of used storage slots.\\n *\\n * Instead of storing each checkpoint in a separate storage slot, this library\\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\\n *\\n * @dev Definitions:\\n * - Checkpoint: A record of an APR change\\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\\n * - History: A dynamic array of packs\\n * - Reference: A storage pointer to a checkpoint in the APR history\\n * - CheckpointData: An in-memory representation of a checkpoint data\\n *\\n * @dev Value limitation:\\n * This library can accommodate APRs only up to 65.536%. This is however sufficient for\\n * APR in LToken contract, which is expected to remain below 10%.\\n *\\n * @dev For further details, see \\\"APRHistory\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary APRHistory {\\n /**\\n * @notice Represents data of a checkpoint extracted from the on-chain history.\\n * For on-chain representation see \\\"Pack\\\" struct.\\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\\n * @param timestamp Timestamp of the checkpoint's creation.\\n */\\n struct CheckpointData {\\n uint16 aprUD7x3; // Allows up to 65.536%\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n }\\n\\n /**\\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\\n * @param aprsUD7x3 Array of checkpoints' APRs.\\n * @param timestamps Array of checkpoints' timestamps.\\n * @param cursor Index of the next checkpoint to be written.\\n */\\n struct Pack {\\n uint16[4] aprsUD7x3;\\n uint40[4] timestamps;\\n uint32 cursor;\\n }\\n\\n /**\\n * @notice Represents a storage pointer to a specific checkpoint in the history.\\n * @param packIndex Index of the pack the checkpoint belongs to.\\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\\n */\\n struct Reference {\\n uint256 packIndex;\\n uint32 cursorIndex;\\n }\\n\\n /**\\n * @notice Compares two checkpoints references.\\n * @param ref1 The first reference to compare.\\n * @param ref2 The second reference to compare.\\n * @return Whether the two references points to the same checkpoint.\\n */\\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\\n }\\n\\n /**\\n * @notice Returns the reference of the checkpoint that should come right after the\\n * referenced checkpoint in the APR history.\\n * @param ref The reference to be incremented.\\n * @return The incremented reference.\\n */\\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L1\\\");\\n\\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\\n //\\n // Else, return ref of next slot in current pack\\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\\n }\\n\\n /**\\n * @notice Extracts checkpoint data from a given reference and in APR history.\\n * @param self The APR history to extract the checkpoint from.\\n * @param ref The reference of the checkpoint data to extract.\\n * @return The extracted checkpoint's data.\\n */\\n function getDataFromReference(\\n Pack[] storage self,\\n Reference memory ref\\n ) public view returns (CheckpointData memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L2\\\");\\n\\n // Ensure pack index of the given ref exists in history\\n require(ref.packIndex < self.length, \\\"L3\\\");\\n\\n // Retrieve pack data from history\\n Pack memory pack = self[ref.packIndex];\\n\\n // Ensure cursor index of the given ref has been written\\n require(ref.cursorIndex < pack.cursor, \\\"L4\\\");\\n\\n // Build and return the checkpoint data\\n return\\n CheckpointData({\\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\\n timestamp: pack.timestamps[ref.cursorIndex]\\n });\\n }\\n\\n /**\\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\\n * @param self The history to extract the reference from.\\n * @return The reference of the latest checkpoint.\\n */\\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\\n // Ensure the given history is not empty\\n require(self.length != 0, \\\"L5\\\");\\n\\n // Retrieve latest pack's index and cursor\\n uint256 packIndex = self.length - 1;\\n uint32 packCursor = self[packIndex].cursor;\\n\\n // If this is the first pack ever, ensure it is not empty\\n if (packIndex == 0) require(packCursor != 0, \\\"L6\\\");\\n\\n // If the pack is empty, return ref of previous pack's latest slot\\n if (packCursor == 0) return Reference(packIndex - 1, 3);\\n //\\n // Else, return ref of previous slot in current pack\\n else return Reference(packIndex, packCursor - 1);\\n }\\n\\n /**\\n * @notice Appends a new empty pack to the end of the given APR history array.\\n * @param self The APR history to append an empty to.\\n */\\n function newBlankPack(Pack[] storage self) internal {\\n // If history is not empty, ensure the latest pack is full\\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \\\"L7\\\");\\n\\n // Push a new blank pack to the history array\\n self.push(\\n Pack({\\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\\n cursor: 0\\n })\\n );\\n }\\n\\n /**\\n * @notice Write a new APR checkpoint at the end of the given history array.\\n * @param self The array of packs to write the new checkpoint to.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\\n // Determine the reference where the new checkpoint should be written\\n Reference memory newRef = self.length == 0\\n ? Reference(0, 0)\\n : incrementReference(getLatestReference(self));\\n\\n // If pack to be written doesn't exist yet, push a new blank pack in history\\n if (newRef.packIndex >= self.length) newBlankPack(self);\\n\\n // Retrieve the pack where the new checkpoint will be stored\\n Pack memory pack = self[newRef.packIndex];\\n\\n // Add new checkpoint's data to the pack\\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\\n\\n // Increment the pack's cursor\\n pack.cursor++;\\n\\n // Write the updated pack in storage\\n self[newRef.packIndex] = pack;\\n }\\n\\n /**\\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\\n * @param self The history array to read APR from.\\n * @return The latest checkpoint's APR.\\n */\\n function getAPR(Pack[] storage self) public view returns (uint16) {\\n // Retrieve the latest checkpoint data\\n Reference memory ref = getLatestReference(self);\\n CheckpointData memory data = getDataFromReference(self, ref);\\n\\n // Return the latest checkpoint's APR\\n return data.aprUD7x3;\\n }\\n}\\n\",\"keccak256\":\"0x0b3d02a33c5e5be03cefc5192439def2efa43be664c372e83f309be34fd476b7\",\"license\":\"MIT\"},\"contracts/src/libs/SUD.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title SUD\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice SUD serves as an intermediary number format for calculations within this\\n * codebase. It ensures consistency and reduces precision losses. This library\\n * facilitates conversions between various number formats and the SUD format.\\n *\\n * @dev Intuition:\\n * This codebase employs the UD (unsigned decimal fixed-point numbers) format to\\n * represent both percentage rates and tokens amounts.\\n *\\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\\n * the decimals() value of the involved tokens.\\n *\\n * Three challenges arise from this:\\n * 1) To compute values together, it's essential that they are in the same format\\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\\n * precision loss (because division shrinks). A common approach is to scale up and\\n * down values by a few decimals before and after performing calculations.\\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\\n * be shrunk in case token's decimals number is in [0, 2].\\n *\\n * To address these challenges, this library provides the SUD format, which acts as a\\n * consistent and scaled intermediate format to perform calculations.\\n *\\n * SUD is an acronym for either \\\"Scaled UD\\\" or \\\"Safe UD\\\".\\n *\\n * @dev Definitions:\\n * - Integer: A number without fractional part, e.g., block.timestamp\\n * - UD: A decimal unsigned fixed-point number. The \\\"UD\\\" notation is inspired from\\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\\n * - Amount: A token amount. A UD with an unknown repartition of digits between integral\\n * and fractional parts (as token amounts have variable decimal numbers)\\n * - Rate: A percentage rate. An UD with 7 integral digits and 3 fractional ones (= UD7x3)\\n * - SUD: An intermediate format to perform calculations involving Rates and Amounts. A UD\\n * with 3 more decimals than the involved UD with the highest decimals number. As\\n * rates are represented by UD7x3, a SUD number has at least 6 decimals (3+3) and\\n * so ranges from UD71x6 to UD0x77 formats.\\n *\\n * @dev A conversion library:\\n * This library provides utilities to perform the following conversions:\\n * - Amount <--> SUD\\n * - Rate (UD7x3) <--> SUD\\n * - Integer <--> SUD\\n *\\n * @dev Why scaling by 3 decimals?\\n * - It provides an adequate degree of precision for this codebase,\\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\\n * the involved token's decimal number, so is gas efficient.\\n *\\n * @dev Why internal functions?\\n * The functions of this library are not set to external because incorporating them\\n * directly into contracts is more gas-efficient. Given their minimal size and frequent\\n * usage in the InvestUpgradeable, LDYStaking, and LToken contracts, any bytecode savings\\n * from making them external are negated by the additional bytecode required for external\\n * calls to this library. This can be observed by comparing the output of `bun cc:size`\\n * when those functions's visibility is set to external or internal.\\n *\\n * @dev Precision warning:\\n * While this library mitigates precision loss during calculations on UD numbers, it's\\n * important to note that tokens with lower decimal counts and supply inherently suffer\\n * more from precision loss. Conversely, tokens with higher decimal counts and supply\\n * will experience less precision loss.\\n *\\n * @dev For further details, see \\\"SUD\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary SUD {\\n /**\\n * @notice Retrieves decimals number of the given ERC20 contract address.\\n * @param tokenAddress The address to retrieve decimals number from.\\n * @return decimals The decimals number of the given ERC20 contract address.\\n */\\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\\n }\\n\\n /**\\n * @notice Convert a given token amount into SUD format.\\n * @param nAmount The token amount to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The amount in SUD format\\n */\\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\\n\\n // Else return a number with decimals+3 fractional digits\\n return nAmount * 10 ** 3;\\n }\\n\\n /**\\n * @notice Convert a given SUD number into token amount format.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nAmount The number in amount format\\n */\\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** 3;\\n }\\n\\n /**\\n * @notice Converts a given UD7x3 rate into SUD format.\\n * @param nUD7x3 The UD7x3 rate to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The rate in SUD format.\\n */\\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nUD7x3 * 10 ** 3;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return nUD7x3 * 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given SUD number into a UD7x3 rate.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nUD7x3 The number in UD7x3 rate format.\\n */\\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 3;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given integer into SUD format.\\n * @param n The integer to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The integer in SUD format.\\n */\\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return n * 10 ** 6;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return n * 10 ** (decimals + 3);\\n }\\n\\n /**\\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return n The SUD number as an integer.\\n */\\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 6;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** (decimals + 3);\\n }\\n}\\n\",\"keccak256\":\"0x7297fc67064b5925e26fa5ed3a4ba4b0f64a9162fdf0ebc2aac8649fddce543a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615f916200011f60003960008181611462015281816114a2015281816118fd0152818161193d01526119d00152615f916000f3fe6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061549e565b60405180910390f35b34801561041557600080fd5b506104296104243660046154e6565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615512565b610cd5565b005b34801561046757600080fd5b50610459610476366004615512565b610d41565b34801561048757600080fd5b5061045961049636600461552f565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f03660046154e6565b611037565b34801561050157600080fd5b506104296105103660046155a0565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b506104296105453660046154e6565b61141d565b34801561055657600080fd5b5061055f61144e565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615512565b611458565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e53660046154e6565b611537565b3480156105f657600080fd5b506105b26106053660046154e6565b611559565b34801561061657600080fd5b506104596106253660046155e1565b611592565b34801561063657600080fd5b506104596106453660046155e1565b611786565b610459610658366004615692565b6118f3565b34801561066957600080fd5b506104b06119c3565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a43660046155e1565b611a76565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611ab2565b3480156106f157600080fd5b50610459610700366004615512565b611abc565b34801561071157600080fd5b50610459610720366004615735565b611c13565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615512565b611cc4565b34801561077057600080fd5b50610459611ce2565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c23660046155e1565b611d18565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b506104596108013660046155e1565b6120d4565b34801561081257600080fd5b506104596108213660046154e6565b612258565b34801561083257600080fd5b506105b2610841366004615512565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b26122bd565b34801561087e57600080fd5b5061045961088d366004615752565b61232c565b34801561089e57600080fd5b506103f3612563565b3480156108b357600080fd5b506104b06108c2366004615512565b612572565b3480156108d357600080fd5b506104596108e2366004615512565b612590565b6104596108f53660046155e1565b6125eb565b34801561090657600080fd5b506104296109153660046154e6565b612952565b34801561092657600080fd5b50610459610935366004615512565b6129d8565b34801561094657600080fd5b50610459610955366004615752565b612a03565b34801561096657600080fd5b506104296109753660046154e6565b612d39565b34801561098657600080fd5b50610459612d47565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb3660046155e1565b612e30565b3480156109dc57600080fd5b506109f06109eb3660046154e6565b612f87565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a203660046155e1565b6130a3565b348015610a3157600080fd5b50610a3a6130b4565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615512565b61312c565b348015610af357600080fd5b50610459613139565b348015610b0857600080fd5b506104b06131fa565b348015610b1d57600080fd5b506104b0610b2c366004615752565b613281565b348015610b3d57600080fd5b50610459610b4c36600461579d565b6132ac565b348015610b5d57600080fd5b506105b2610b6c3660046155e1565b613319565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b0613344565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615512565b61334f565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461579d565b613384565b6060609a8054610c38906157ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610c64906157ba565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc98185856133f1565b60019150505b92915050565b610cdd613515565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613515565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed091908101906157ee565b9050610f1d87878784604051602001610ee99190615865565b60405160208183030381529060405285604051602001610f099190615895565b604051602081830303815290604052613576565b610f26836135ba565b610f2f306135ea565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f736122bd565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c6122bd565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e613344565b61102891906158d4565b61103291906158d4565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613694565b61108185858561370e565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e06138ca565b610300546102ff5460009182915b808210156113c05761afc85a106113c05760006102ff8381548110611115576111156158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150156113ad57805161116490613912565b156111e6576102ff838154811061117d5761117d6158e7565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa4909101556113ad565b60026111f06131fa565b6111fa91906158fd565b81602001516001600160601b031611156112c65760208101516102ff5460405160019233928792600080516020615f3c833981519152926112419290918291600391615941565b60405180910390a46102ff838154811061125d5761125d6158e7565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec909101556113ad565b6000806112e4836000015184602001516001600160601b0316612f87565b91509150856102fe546112f79190615975565b821115611306575050506113c0565b61131081886158d4565b965061131c82876158d4565b9550600183600001516001600160a01b031686600080516020615f3c83398151915286602001518660026000196040516113599493929190615988565b60405180910390a46102ff8581548110611375576113756158e7565b600091825260208220015582516113aa908361139a6102c6546001600160a01b031690565b6001600160a01b03169190613982565b50505b826113b7816159ac565b935050506110ee565b836102fc60008282546113d391906158d4565b92505081905550826102fe60008282546113ed9190615975565b909155506113fd905084846158d4565b6102fd600082825461140f9190615975565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b60006110326139e5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114a05760405162461bcd60e51b8152600401610d15906159c5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114e9600080516020615ef5833981519152546001600160a01b031690565b6001600160a01b03161461150f5760405162461bcd60e51b8152600401610d1590615a11565b61151881613a5b565b6040805160008082526020820190925261153491839190613a63565b50565b600033610cc981858561154a8383613281565b61155491906158d4565b6133f1565b610292602052816000526040600020818154811061157657600080fd5b6000918252602090912001546001600160a01b03169150829050565b61159a6138ca565b336115a481613912565b156115c15760405162461bcd60e51b8152600401610d1590615a5d565b6115ca33611cc4565b8211156115ff5760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd5461161491906158d4565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169a9190615a79565b101580156116ab57506102fe548411155b905081806116b65750805b6116e85760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116f53387612f87565b91509150806102fc600082825461170c91906158d4565b92505081905550816102fe60008282546117269190615975565b9091555060019050336001600160a01b0316600019600080516020615f3c833981519152898660026000196040516117619493929190615a92565b60405180910390a46117733382613bce565b61177d3383613d15565b50505050505050565b61178e6138ca565b3361179881613912565b156117b55760405162461bcd60e51b8152600401610d1590615a5d565b60006102ff83815481106117cb576117cb6158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118475760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd60008282546118679190615975565b90915550506102ff805484908110611881576118816158e7565b6000918252602082200155600181600001516001600160a01b031684600080516020615f3c8339815191528460200151856020015160016000196040516118cb9493929190615941565b60405180910390a46118ee816000015182602001516001600160601b0316613d42565b505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361193b5760405162461bcd60e51b8152600401610d15906159c5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611984600080516020615ef5833981519152546001600160a01b031690565b6001600160a01b0316146119aa5760405162461bcd60e51b8152600401610d1590615a11565b6119b382613a5b565b6119bf82826001613a63565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a635760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615ef583398151915290565b6103018181548110611a8757600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613e17565b611ac4613515565b610302546000199060005b81811015611b2957836001600160a01b03166103028281548110611af557611af56158e7565b6000918252602090912001546001600160a01b031603611b1757809250611b29565b80611b21816159ac565b915050611acf565b506000198213611b615760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b6f600183615975565b81548110611b7f57611b7f6158e7565b60009182526020909120015461030280546001600160a01b039092169184908110611bac57611bac6158e7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611bec57611bec615aad565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611c1b613515565b60405163433e3bad60e11b8152610290600482015261ffff82166024820152730165878A594ca255338adfa4d48449f69242Eb8F9063867c775a9060440160006040518083038186803b158015611c7157600080fd5b505af4158015611c85573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611ccf8261312c565b611cd883612572565b610ccf91906158d4565b611cea613515565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d625760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d6a6138ca565b60006102ff8281548110611d8057611d806158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611df15760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611dfc90613912565b15611e2f5760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611e396131fa565b611e4391906158fd565b81602001516001600160601b031611611e845760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611ea2836000015184602001516001600160601b0316612f87565b915091506000611ebb6102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190615a79565b9050806102fe54611f3a91906158d4565b831115611f6f5760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f8291906158d4565b9250508190555083602001516001600160601b03166102fd6000828254611fa99190615975565b9091555050610300548503611fcf576103008054906000611fc9836159ac565b91905055505b600184600001516001600160a01b031686600080516020615f3c833981519152876020015187600260001960405161200a9493929190615988565b60405180910390a46102ff8581548110612026576120266158e7565b600091825260208220015580831161206857612063338551856120526102c6546001600160a01b031690565b6001600160a01b0316929190613e86565b6120c5565b60006120748285615975565b9050806102fe60008282546120899190615975565b909155506120a99050338651846120526102c6546001600160a01b031690565b84516120c3908261139a6102c6546001600160a01b031690565b505b6120cd613ebe565b5050505050565b6102fb546001600160a01b0316336001600160a01b03161461211e5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6121266138ca565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190615a79565b8111156121d65760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe546121e791906158d4565b90506121f16131fa565b8111156122265760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe600082825461223991906158d4565b909155506119bf90503330846120526102c6546001600160a01b031690565b612260613515565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122b35760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119bf8282613f27565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615ac3565b6123346138ca565b8161233e81613912565b1561235b5760405162461bcd60e51b8152600401610d1590615a5d565b8161236581613912565b156123825760405162461bcd60e51b8152600401610d1590615a5d565b6001600160a01b038481166000908152610291602052604090205416156123d15760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b03841661240d5760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166124495760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124905760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b6124986122bd565b6001600160a01b0316336001600160a01b031614806124bf5750336001600160a01b038516145b6124f15760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124fc846001614019565b612507836001614019565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c38906157ba565b6001600160a01b038116600090815260976020526040812054610ccf565b612598613515565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125f36138ca565b336125fd81613912565b1561261a5760405162461bcd60e51b8152600401610d1590615a5d565b61262333611cc4565b8211156126585760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b038211156126955760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660aa87bee538000146126d15760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b600060405180604001604052806126e53390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561275d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127819190615a79565b101580156127925750600061030054115b156128005761030080549060006127a883615ae0565b9190505550610300549050816102ff82815481106127c8576127c86158e7565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561286a565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9092019190915590546128679190615975565b90505b836102fd600082825461287d91906158d4565b9091555060019050336001600160a01b031682600080516020615f3c833981519152878860006000196040516128b69493929190615a92565b60405180910390a46128c83385613bce565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d8060008114612916576040519150601f19603f3d011682016040523d82523d6000602084013e61291b565b606091505b50509050806120cd5760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b600033816129608286613281565b9050838110156129c05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b6129cd82868684036133f1565b506001949350505050565b6129e0613515565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b612a0b6138ca565b81612a1581613912565b15612a325760405162461bcd60e51b8152600401610d1590615a5d565b81612a3c81613912565b15612a595760405162461bcd60e51b8152600401610d1590615a5d565b6001600160a01b038416612a955760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612ad15760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612ad96122bd565b6001600160a01b0316336001600160a01b03161480612b005750336001600160a01b038516145b612b325760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b855760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b90846001614019565b612b9b836001614019565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612c26576001600160a01b0385811660009081526102926020526040902080549188169183908110612bf257612bf26158e7565b6000918252602090912001546001600160a01b031603612c1457809150612c26565b80612c1e816159ac565b915050612ba1565b506000811215612c3857612c38615af7565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c7c90600190615975565b81548110612c8c57612c8c6158e7565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612cca57612cca6158e7565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612d1057612d10615aad565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561370e565b612d4f613515565b60006102fe54612d686102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd29190615a79565b612ddc9190615975565b905060008111612e145760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b611534612e2a6102c6546001600160a01b031690565b82613f27565b612e386138ca565b33612e4281613912565b15612e5f5760405162461bcd60e51b8152600401610d1590615a5d565b81612e736102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190615a79565b1015612f1e5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612f3191906158d4565b9091555060009050336001600160a01b0316600019600080516020615f3c83398151915285866002600019604051612f6c9493929190615a92565b60405180910390a4612f7e33836140ee565b506119bf613ebe565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ffe9190615a79565b1061300e5750819050600061309c565b600061302b61302661028e546001600160a01b031690565b61416f565b9050600061303985836141dc565b6102fb5490915060009061305a90600160a01b900463ffffffff168461421a565b90506000613069606485614246565b6130738385615b0d565b61307d91906158fd565b90506130898185614274565b94506130958588615975565b9550505050505b9250929050565b6102ff8181548110611a8757600080fd5b60405163106d64cf60e31b81526102906004820152600090730165878A594ca255338adfa4d48449f69242Eb8F9063836b267890602401602060405180830381865af4158015613108573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b24565b6000610ccf8260016142ab565b613141613515565b60006102fc541161317a5760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131b65760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe60008282546131cc9190615975565b90915550506102fc805460009091556115346131e66122bd565b8261139a6102c6546001600160a01b031690565b60008061321361302661028e546001600160a01b031690565b9050600061322861322261100c565b836141dc565b6102fb5490915060009061324990600160c01b900463ffffffff168461421a565b90506000613258606485614246565b6132628385615b0d565b61326c91906158fd565b90506132788185614274565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6132b4613515565b614e2063ffffffff821611156132f25760405162461bcd60e51b815260206004820152600360248201526209870760eb1b6044820152606401610d15565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061332a57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b613357613515565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b61338c613515565b61271063ffffffff821611156133ca5760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166134535760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134b45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361351e6122bd565b6001600160a01b0316146135745760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661359d5760405162461bcd60e51b8152600401610d1590615b41565b6135a8858585614811565b6135b2828261486b565b6120cd61489c565b600054610100900460ff166135e15760405162461bcd60e51b8152600401610d1590615b41565b611534816148c3565b600054610100900460ff166136115760405162461bcd60e51b8152600401610d1590615b41565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b8152610290600482015260006024820152730165878A594ca255338adfa4d48449f69242Eb8F9063867c775a9060440160006040518083038186803b15801561368057600080fd5b505af41580156120cd573d6000803e3d6000fd5b60006136a08484613281565b9050600019811461370857818110156136fb5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b61370884848484036133f1565b50505050565b6001600160a01b0383166137725760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137d45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b6137df838383614965565b6001600160a01b038316600090815260976020526040902054818110156138575760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138b79086815260200190565b60405180910390a36137088484846149a4565b6138d2611ab2565b156135745760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa15801561395e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615b8c565b6040516001600160a01b0383166024820152604481018290526118ee90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614aad565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa925050508015613a4c575060408051601f3d908101601f19168201909252613a4991810190615bae565b60015b613a565750601290565b919050565b611534613515565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a96576118ee83614b82565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613af0575060408051601f3d908101601f19168201909252613aed91810190615a79565b60015b613b535760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615ef58339815191528114613bc25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118ee838383614c1e565b6001600160a01b038216613c2e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613c3a82600083614965565b6001600160a01b03821660009081526097602052604090205481811015613cae5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118ee836000846149a4565b6000613d213383613bce565b6102c654613d39906001600160a01b03168484613982565b50600192915050565b6001600160a01b038216613d985760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613da460008383614965565b8060996000828254613db691906158d4565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36119bf600083836149a4565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613e62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b8c565b6040516001600160a01b03808516602483015283166044820152606481018290526137089085906323b872dd60e01b906084016139ae565b6000613ec86131fa565b9050806102fe5411613ed75750565b6000816102fe54613ee89190615975565b9050806102fe6000828254613efd9190615975565b90915550506102fb546119bf906001600160a01b03168261139a6102c6546001600160a01b031690565b613f2f613515565b60008111613f655760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fd19190615a79565b10156140055760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118ee6001600160a01b0382163384613982565b6102935460ff1615614029575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603614057575050565b6001600160a01b0380831660009081526102916020526040902054168015614083576118ee8183614019565b600061408f84846142ab565b905080156140e557610293805460ff1916600117905560006140b18583614c43565b610293805460ff191690559050806140e3576001600160a01b038516600090815261028f602052604090206003018290555b505b61370884614c9a565b60003330810361414c5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c654614165906001600160a01b0316823086613e86565b610cc98484613d42565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156141af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d39190615bae565b60ff1692915050565b6000600382101561420e576141f2826006615975565b6141fd90600a615cb5565b6142079084615b0d565b9050610ccf565b611087836103e8615b0d565b6000600382101561423157614207836103e8615b0d565b61423c82600a615cb5565b6110879084615b0d565b6000600382101561425e5761420783620f4240615b0d565b6142698260036158d4565b61423c90600a615cb5565b6000600382101561429f5761428a826006615975565b61429590600a615cb5565b61420790846158fd565b6110876103e8846158fd565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161431c85614dfc565b82515190915064ffffffffff161580614333575080155b1561434357600092505050610ccf565b815160200151604051630b27cfb160e31b8152600090730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d889061438790610290908690600401615cc1565b6040805180830381865af41580156143a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143c79190615ce5565b60405163038255fd60e11b81526102906004820152909150600090730165878A594ca255338adfa4d48449f69242Eb8F90630704abfa906024016040805180830381865af415801561441d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144419190615d30565b905084602001519550730165878A594ca255338adfa4d48449f69242Eb8F634ead0c5384836040518363ffffffff1660e01b8152600401614483929190615d5c565b602060405180830381865af41580156144a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144c49190615b8c565b6147d557604051633e1e5c5360e11b8152600090730165878A594ca255338adfa4d48449f69242Eb8F90637c3cb8a690614502908790600401615d90565b6040805180830381865af415801561451e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145429190615d30565b604051630b27cfb160e31b8152909150600090730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d889061458390610290908690600401615cc1565b6040805180830381865af415801561459f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145c39190615ce5565b875151602082015186519293506145f1928c6145e05760006145e2565b8b5b6145ec908b6158d4565b614ea5565b6145fb90896158d4565b97505b819450809350730165878A594ca255338adfa4d48449f69242Eb8F634ead0c5386856040518363ffffffff1660e01b815260040161463d929190615d5c565b602060405180830381865af415801561465a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061467e9190615b8c565b6147a857604051633e1e5c5360e11b8152730165878A594ca255338adfa4d48449f69242Eb8F90637c3cb8a6906146b9908890600401615d90565b6040805180830381865af41580156146d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f99190615d30565b604051630b27cfb160e31b8152909250730165878A594ca255338adfa4d48449f69242Eb8F9063593e7d889061473790610290908690600401615cc1565b6040805180830381865af4158015614753573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147779190615ce5565b90506147978460200151826020015186600001518c6145e05760006145e2565b6147a190896158d4565b97506145fe565b6147c284602001514286600001518c6145e05760006145e2565b6147cc90896158d4565b97505050614806565b84515182516147f9919042908a6147ed5760006147ef565b895b6145ec90896158d4565b61480390876158d4565b95505b505050505092915050565b600054610100900460ff166148385760405162461bcd60e51b8152600401610d1590615b41565b61484061489c565b61484983614f91565b614851614fc1565b61485a82614ff0565b6148638161503a565b6118ee61489c565b600054610100900460ff166148925760405162461bcd60e51b8152600401610d1590615b41565b6119bf8282615084565b600054610100900460ff166135745760405162461bcd60e51b8152600401610d1590615b41565b600054610100900460ff166148ea5760405162461bcd60e51b8152600401610d1590615b41565b306001600160a01b038216036149425760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6149708383836150c4565b6001600160a01b0383161561498a5761498a836001614019565b6001600160a01b038216156118ee576118ee826001614019565b6001600160a01b03831615806149c157506001600160a01b038216155b15614a01577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f6149ef61100c565b60405190815260200160405180910390a15b60005b61030254811015613708576103028181548110614a2357614a236158e7565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b158015614a8257600080fd5b505af1158015614a96573d6000803e3d6000fd5b505050508080614aa5906159ac565b915050614a04565b6000614b02826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166151259092919063ffffffff16565b9050805160001480614b23575080806020019051810190614b239190615b8c565b6118ee5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614bef5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615ef583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614c2783615134565b600082511180614c345750805b156118ee576137088383615174565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614c7985612572565b60408051918252602082018690520160405180910390a2613d398383613d42565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b81526102906004820152730165878A594ca255338adfa4d48449f69242Eb8F90630704abfa906024016040805180830381865af4158015614d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d3c9190615d30565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b038216600090815261029260205260409020548110156119bf576001600160a01b0382166000908152610292602052604090208054614dea919083908110614dd057614dd06158e7565b6000918252602090912001546001600160a01b0316614c9a565b80614df4816159ac565b915050614d7f565b6000614e0782615199565b614e1190826158d4565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e9f576001600160a01b0383166000908152610292602052604090208054614e81919083908110614e6757614e676158e7565b6000918252602090912001546001600160a01b0316614dfc565b614e8b90836158d4565b915080614e97816159ac565b915050614e16565b50919050565b600080614ebe61302661028e546001600160a01b031690565b90506000614edc614ecf8888615dad565b64ffffffffff1683614246565b90506000614eee6301e1338084614246565b614ef9600185614246565b614f039084615b0d565b614f0d91906158fd565b90506000614f1f8761ffff168561421a565b90506000614f2e600186614246565b614f388385615b0d565b614f4291906158fd565b90506000614f5088876141dc565b90506000614f5f606488614246565b614f698484615b0d565b614f7391906158fd565b9050614f7f8188614274565b9750505050505050505b949350505050565b600054610100900460ff16614fb85760405162461bcd60e51b8152600401610d1590615b41565b611534816151a4565b600054610100900460ff16614fe85760405162461bcd60e51b8152600401610d1590615b41565b6135746151ee565b600054610100900460ff166150175760405162461bcd60e51b8152600401610d1590615b41565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150615760405162461bcd60e51b8152600401610d1590615b41565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150ab5760405162461bcd60e51b8152600401610d1590615b41565b609a6150b78382615e18565b50609b6118ee8282615e18565b6150cc6138ca565b826150d681613912565b156150f35760405162461bcd60e51b8152600401610d1590615a5d565b826150fd81613912565b1561511a5760405162461bcd60e51b8152600401610d1590615a5d565b6120cd858585615221565b6060614f898484600085615289565b61513d81614b82565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615f1560279139615364565b6000610ccf82612572565b600054610100900460ff166151cb5760405162461bcd60e51b8152600401610d1590615b41565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166152155760405162461bcd60e51b8152600401610d1590615b41565b60c9805460ff19169055565b615229611ab2565b156118ee5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152ea5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516153069190615ed8565b60006040518083038185875af1925050503d8060008114615343576040519150601f19603f3d011682016040523d82523d6000602084013e615348565b606091505b5091509150615359878383876153dc565b979650505050505050565b6060600080856001600160a01b0316856040516153819190615ed8565b600060405180830381855af49150503d80600081146153bc576040519150601f19603f3d011682016040523d82523d6000602084013e6153c1565b606091505b50915091506153d2868383876153dc565b9695505050505050565b6060831561544b578251600003615444576001600160a01b0385163b6154445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614f89565b614f8983838151156154605781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061549e565b60005b8381101561549557818101518382015260200161547d565b50506000910152565b60208152600082518060208401526154bd81604085016020870161547a565b601f01601f19169190910160400192915050565b6001600160a01b038116811461153457600080fd5b600080604083850312156154f957600080fd5b8235615504816154d1565b946020939093013593505050565b60006020828403121561552457600080fd5b8135611087816154d1565b600080600080600060a0868803121561554757600080fd5b8535615552816154d1565b94506020860135615562816154d1565b93506040860135615572816154d1565b92506060860135615582816154d1565b91506080860135615592816154d1565b809150509295509295909350565b6000806000606084860312156155b557600080fd5b83356155c0816154d1565b925060208401356155d0816154d1565b929592945050506040919091013590565b6000602082840312156155f357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715615633576156336155fa565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715615662576156626155fa565b604052919050565b600067ffffffffffffffff821115615684576156846155fa565b50601f01601f191660200190565b600080604083850312156156a557600080fd5b82356156b0816154d1565b9150602083013567ffffffffffffffff8111156156cc57600080fd5b8301601f810185136156dd57600080fd5b80356156f06156eb8261566a565b615639565b81815286602083850101111561570557600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff8116811461153457600080fd5b60006020828403121561574757600080fd5b813561108781615725565b6000806040838503121561576557600080fd5b8235615770816154d1565b91506020830135615780816154d1565b809150509250929050565b63ffffffff8116811461153457600080fd5b6000602082840312156157af57600080fd5b81356110878161578b565b600181811c908216806157ce57607f821691505b602082108103614e9f57634e487b7160e01b600052602260045260246000fd5b60006020828403121561580057600080fd5b815167ffffffffffffffff81111561581757600080fd5b8201601f8101841361582857600080fd5b80516158366156eb8261566a565b81815285602083850101111561584b57600080fd5b61585c82602083016020860161547a565b95945050505050565b6702632b233b4ba3c960c51b81526000825161588881600885016020870161547a565b9190910160080192915050565b601360fa1b8152600082516158b181600185016020870161547a565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf6158be565b634e487b7160e01b600052603260045260246000fd5b60008261591a57634e487b7160e01b600052601260045260246000fd5b500490565b6004811061593d57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b0385811682528416602082015260808101615966604083018561591f565b82606083015295945050505050565b81810381811115610ccf57610ccf6158be565b6001600160601b03851681526020810184905260808101615966604083018561591f565b6000600182016159be576159be6158be565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b600060208284031215615a8b57600080fd5b5051919050565b8481526020810184905260808101615966604083018561591f565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615ad557600080fd5b8151611087816154d1565b600081615aef57615aef6158be565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf6158be565b600060208284031215615b3657600080fd5b815161108781615725565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615b9e57600080fd5b8151801515811461108757600080fd5b600060208284031215615bc057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615c0c578160001904821115615bf257615bf26158be565b80851615615bff57918102915b93841c9390800290615bd6565b509250929050565b600082615c2357506001610ccf565b81615c3057506000610ccf565b8160018114615c465760028114615c5057615c6c565b6001915050610ccf565b60ff841115615c6157615c616158be565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615c8f575081810a610ccf565b615c998383615bd1565b8060001904821115615cad57615cad6158be565b029392505050565b60006110878383615c14565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615cf757600080fd5b615cff615610565b8251615d0a81615725565b8152602083015164ffffffffff81168114615d2457600080fd5b60208201529392505050565b600060408284031215615d4257600080fd5b615d4a615610565b825181526020830151615d248161578b565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615dcb57615dcb6158be565b5092915050565b601f8211156118ee57600081815260208120601f850160051c81016020861015615df95750805b601f850160051c820191505b8181101561100457828155600101615e05565b815167ffffffffffffffff811115615e3257615e326155fa565b615e4681615e4084546157ba565b84615dd2565b602080601f831160018114615e7b5760008415615e635750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615eaa57888601518255948401946001909101908401615e8b565b5085821015615ec85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615eea81846020870161547a565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564d58e94604d90293a1c1ad95bfe6a6e6c352c33c5774a4b6b4f4b6f7460da29c5a264697066735822122075fca9467f2456a5739b6b2931262fe9508bbdbfb6838b51523f93bfbd0daa9764736f6c63430008120033", + "deployedBytecode": "0x6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061549e565b60405180910390f35b34801561041557600080fd5b506104296104243660046154e6565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615512565b610cd5565b005b34801561046757600080fd5b50610459610476366004615512565b610d41565b34801561048757600080fd5b5061045961049636600461552f565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f03660046154e6565b611037565b34801561050157600080fd5b506104296105103660046155a0565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b506104296105453660046154e6565b61141d565b34801561055657600080fd5b5061055f61144e565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615512565b611458565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e53660046154e6565b611537565b3480156105f657600080fd5b506105b26106053660046154e6565b611559565b34801561061657600080fd5b506104596106253660046155e1565b611592565b34801561063657600080fd5b506104596106453660046155e1565b611786565b610459610658366004615692565b6118f3565b34801561066957600080fd5b506104b06119c3565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a43660046155e1565b611a76565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611ab2565b3480156106f157600080fd5b50610459610700366004615512565b611abc565b34801561071157600080fd5b50610459610720366004615735565b611c13565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615512565b611cc4565b34801561077057600080fd5b50610459611ce2565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c23660046155e1565b611d18565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b506104596108013660046155e1565b6120d4565b34801561081257600080fd5b506104596108213660046154e6565b612258565b34801561083257600080fd5b506105b2610841366004615512565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b26122bd565b34801561087e57600080fd5b5061045961088d366004615752565b61232c565b34801561089e57600080fd5b506103f3612563565b3480156108b357600080fd5b506104b06108c2366004615512565b612572565b3480156108d357600080fd5b506104596108e2366004615512565b612590565b6104596108f53660046155e1565b6125eb565b34801561090657600080fd5b506104296109153660046154e6565b612952565b34801561092657600080fd5b50610459610935366004615512565b6129d8565b34801561094657600080fd5b50610459610955366004615752565b612a03565b34801561096657600080fd5b506104296109753660046154e6565b612d39565b34801561098657600080fd5b50610459612d47565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb3660046155e1565b612e30565b3480156109dc57600080fd5b506109f06109eb3660046154e6565b612f87565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a203660046155e1565b6130a3565b348015610a3157600080fd5b50610a3a6130b4565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615512565b61312c565b348015610af357600080fd5b50610459613139565b348015610b0857600080fd5b506104b06131fa565b348015610b1d57600080fd5b506104b0610b2c366004615752565b613281565b348015610b3d57600080fd5b50610459610b4c36600461579d565b6132ac565b348015610b5d57600080fd5b506105b2610b6c3660046155e1565b613319565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b0613344565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615512565b61334f565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461579d565b613384565b6060609a8054610c38906157ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610c64906157ba565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc98185856133f1565b60019150505b92915050565b610cdd613515565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613515565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed091908101906157ee565b9050610f1d87878784604051602001610ee99190615865565b60405160208183030381529060405285604051602001610f099190615895565b604051602081830303815290604052613576565b610f26836135ba565b610f2f306135ea565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f736122bd565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c6122bd565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e613344565b61102891906158d4565b61103291906158d4565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613694565b61108185858561370e565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e06138ca565b610300546102ff5460009182915b808210156113c05761afc85a106113c05760006102ff8381548110611115576111156158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150156113ad57805161116490613912565b156111e6576102ff838154811061117d5761117d6158e7565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa4909101556113ad565b60026111f06131fa565b6111fa91906158fd565b81602001516001600160601b031611156112c65760208101516102ff5460405160019233928792600080516020615f3c833981519152926112419290918291600391615941565b60405180910390a46102ff838154811061125d5761125d6158e7565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec909101556113ad565b6000806112e4836000015184602001516001600160601b0316612f87565b91509150856102fe546112f79190615975565b821115611306575050506113c0565b61131081886158d4565b965061131c82876158d4565b9550600183600001516001600160a01b031686600080516020615f3c83398151915286602001518660026000196040516113599493929190615988565b60405180910390a46102ff8581548110611375576113756158e7565b600091825260208220015582516113aa908361139a6102c6546001600160a01b031690565b6001600160a01b03169190613982565b50505b826113b7816159ac565b935050506110ee565b836102fc60008282546113d391906158d4565b92505081905550826102fe60008282546113ed9190615975565b909155506113fd905084846158d4565b6102fd600082825461140f9190615975565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b60006110326139e5565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114a05760405162461bcd60e51b8152600401610d15906159c5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114e9600080516020615ef5833981519152546001600160a01b031690565b6001600160a01b03161461150f5760405162461bcd60e51b8152600401610d1590615a11565b61151881613a5b565b6040805160008082526020820190925261153491839190613a63565b50565b600033610cc981858561154a8383613281565b61155491906158d4565b6133f1565b610292602052816000526040600020818154811061157657600080fd5b6000918252602090912001546001600160a01b03169150829050565b61159a6138ca565b336115a481613912565b156115c15760405162461bcd60e51b8152600401610d1590615a5d565b6115ca33611cc4565b8211156115ff5760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd5461161491906158d4565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611676573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169a9190615a79565b101580156116ab57506102fe548411155b905081806116b65750805b6116e85760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116f53387612f87565b91509150806102fc600082825461170c91906158d4565b92505081905550816102fe60008282546117269190615975565b9091555060019050336001600160a01b0316600019600080516020615f3c833981519152898660026000196040516117619493929190615a92565b60405180910390a46117733382613bce565b61177d3383613d15565b50505050505050565b61178e6138ca565b3361179881613912565b156117b55760405162461bcd60e51b8152600401610d1590615a5d565b60006102ff83815481106117cb576117cb6158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118475760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd60008282546118679190615975565b90915550506102ff805484908110611881576118816158e7565b6000918252602082200155600181600001516001600160a01b031684600080516020615f3c8339815191528460200151856020015160016000196040516118cb9493929190615941565b60405180910390a46118ee816000015182602001516001600160601b0316613d42565b505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361193b5760405162461bcd60e51b8152600401610d15906159c5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611984600080516020615ef5833981519152546001600160a01b031690565b6001600160a01b0316146119aa5760405162461bcd60e51b8152600401610d1590615a11565b6119b382613a5b565b6119bf82826001613a63565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a635760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615ef583398151915290565b6103018181548110611a8757600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613e17565b611ac4613515565b610302546000199060005b81811015611b2957836001600160a01b03166103028281548110611af557611af56158e7565b6000918252602090912001546001600160a01b031603611b1757809250611b29565b80611b21816159ac565b915050611acf565b506000198213611b615760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b6f600183615975565b81548110611b7f57611b7f6158e7565b60009182526020909120015461030280546001600160a01b039092169184908110611bac57611bac6158e7565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611bec57611bec615aad565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611c1b613515565b60405163433e3bad60e11b8152610290600482015261ffff8216602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b158015611c7157600080fd5b505af4158015611c85573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611ccf8261312c565b611cd883612572565b610ccf91906158d4565b611cea613515565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d625760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d6a6138ca565b60006102ff8281548110611d8057611d806158e7565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611df15760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611dfc90613912565b15611e2f5760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611e396131fa565b611e4391906158fd565b81602001516001600160601b031611611e845760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611ea2836000015184602001516001600160601b0316612f87565b915091506000611ebb6102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190615a79565b9050806102fe54611f3a91906158d4565b831115611f6f5760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f8291906158d4565b9250508190555083602001516001600160601b03166102fd6000828254611fa99190615975565b9091555050610300548503611fcf576103008054906000611fc9836159ac565b91905055505b600184600001516001600160a01b031686600080516020615f3c833981519152876020015187600260001960405161200a9493929190615988565b60405180910390a46102ff8581548110612026576120266158e7565b600091825260208220015580831161206857612063338551856120526102c6546001600160a01b031690565b6001600160a01b0316929190613e86565b6120c5565b60006120748285615975565b9050806102fe60008282546120899190615975565b909155506120a99050338651846120526102c6546001600160a01b031690565b84516120c3908261139a6102c6546001600160a01b031690565b505b6120cd613ebe565b5050505050565b6102fb546001600160a01b0316336001600160a01b03161461211e5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6121266138ca565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190615a79565b8111156121d65760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe546121e791906158d4565b90506121f16131fa565b8111156122265760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe600082825461223991906158d4565b909155506119bf90503330846120526102c6546001600160a01b031690565b612260613515565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122b35760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119bf8282613f27565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa158015612308573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615ac3565b6123346138ca565b8161233e81613912565b1561235b5760405162461bcd60e51b8152600401610d1590615a5d565b8161236581613912565b156123825760405162461bcd60e51b8152600401610d1590615a5d565b6001600160a01b038481166000908152610291602052604090205416156123d15760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b03841661240d5760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166124495760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124905760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b6124986122bd565b6001600160a01b0316336001600160a01b031614806124bf5750336001600160a01b038516145b6124f15760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124fc846001614019565b612507836001614019565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c38906157ba565b6001600160a01b038116600090815260976020526040812054610ccf565b612598613515565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125f36138ca565b336125fd81613912565b1561261a5760405162461bcd60e51b8152600401610d1590615a5d565b61262333611cc4565b8211156126585760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b038211156126955760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660aa87bee538000146126d15760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b600060405180604001604052806126e53390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561275d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127819190615a79565b101580156127925750600061030054115b156128005761030080549060006127a883615ae0565b9190505550610300549050816102ff82815481106127c8576127c86158e7565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561286a565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9092019190915590546128679190615975565b90505b836102fd600082825461287d91906158d4565b9091555060019050336001600160a01b031682600080516020615f3c833981519152878860006000196040516128b69493929190615a92565b60405180910390a46128c83385613bce565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d8060008114612916576040519150601f19603f3d011682016040523d82523d6000602084013e61291b565b606091505b50509050806120cd5760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b600033816129608286613281565b9050838110156129c05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b6129cd82868684036133f1565b506001949350505050565b6129e0613515565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b612a0b6138ca565b81612a1581613912565b15612a325760405162461bcd60e51b8152600401610d1590615a5d565b81612a3c81613912565b15612a595760405162461bcd60e51b8152600401610d1590615a5d565b6001600160a01b038416612a955760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612ad15760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612ad96122bd565b6001600160a01b0316336001600160a01b03161480612b005750336001600160a01b038516145b612b325760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b855760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b90846001614019565b612b9b836001614019565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612c26576001600160a01b0385811660009081526102926020526040902080549188169183908110612bf257612bf26158e7565b6000918252602090912001546001600160a01b031603612c1457809150612c26565b80612c1e816159ac565b915050612ba1565b506000811215612c3857612c38615af7565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c7c90600190615975565b81548110612c8c57612c8c6158e7565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612cca57612cca6158e7565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612d1057612d10615aad565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561370e565b612d4f613515565b60006102fe54612d686102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd29190615a79565b612ddc9190615975565b905060008111612e145760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b611534612e2a6102c6546001600160a01b031690565b82613f27565b612e386138ca565b33612e4281613912565b15612e5f5760405162461bcd60e51b8152600401610d1590615a5d565b81612e736102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eea9190615a79565b1015612f1e5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612f3191906158d4565b9091555060009050336001600160a01b0316600019600080516020615f3c83398151915285866002600019604051612f6c9493929190615a92565b60405180910390a4612f7e33836140ee565b506119bf613ebe565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ffe9190615a79565b1061300e5750819050600061309c565b600061302b61302661028e546001600160a01b031690565b61416f565b9050600061303985836141dc565b6102fb5490915060009061305a90600160a01b900463ffffffff168461421a565b90506000613069606485614246565b6130738385615b0d565b61307d91906158fd565b90506130898185614274565b94506130958588615975565b9550505050505b9250929050565b6102ff8181548110611a8757600080fd5b60405163106d64cf60e31b8152610290600482015260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063836b267890602401602060405180830381865af4158015613108573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b24565b6000610ccf8260016142ab565b613141613515565b60006102fc541161317a5760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131b65760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe60008282546131cc9190615975565b90915550506102fc805460009091556115346131e66122bd565b8261139a6102c6546001600160a01b031690565b60008061321361302661028e546001600160a01b031690565b9050600061322861322261100c565b836141dc565b6102fb5490915060009061324990600160c01b900463ffffffff168461421a565b90506000613258606485614246565b6132628385615b0d565b61326c91906158fd565b90506132788185614274565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b6132b4613515565b614e2063ffffffff821611156132f25760405162461bcd60e51b815260206004820152600360248201526209870760eb1b6044820152606401610d15565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061332a57600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b613357613515565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b61338c613515565b61271063ffffffff821611156133ca5760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166134535760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134b45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361351e6122bd565b6001600160a01b0316146135745760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661359d5760405162461bcd60e51b8152600401610d1590615b41565b6135a8858585614811565b6135b2828261486b565b6120cd61489c565b600054610100900460ff166135e15760405162461bcd60e51b8152600401610d1590615b41565b611534816148c3565b600054610100900460ff166136115760405162461bcd60e51b8152600401610d1590615b41565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b815261029060048201526000602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b15801561368057600080fd5b505af41580156120cd573d6000803e3d6000fd5b60006136a08484613281565b9050600019811461370857818110156136fb5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b61370884848484036133f1565b50505050565b6001600160a01b0383166137725760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137d45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b6137df838383614965565b6001600160a01b038316600090815260976020526040902054818110156138575760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138b79086815260200190565b60405180910390a36137088484846149a4565b6138d2611ab2565b156135745760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa15801561395e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615b8c565b6040516001600160a01b0383166024820152604481018290526118ee90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614aad565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa925050508015613a4c575060408051601f3d908101601f19168201909252613a4991810190615bae565b60015b613a565750601290565b919050565b611534613515565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a96576118ee83614b82565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613af0575060408051601f3d908101601f19168201909252613aed91810190615a79565b60015b613b535760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615ef58339815191528114613bc25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118ee838383614c1e565b6001600160a01b038216613c2e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613c3a82600083614965565b6001600160a01b03821660009081526097602052604090205481811015613cae5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118ee836000846149a4565b6000613d213383613bce565b6102c654613d39906001600160a01b03168484613982565b50600192915050565b6001600160a01b038216613d985760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613da460008383614965565b8060996000828254613db691906158d4565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36119bf600083836149a4565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613e62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615b8c565b6040516001600160a01b03808516602483015283166044820152606481018290526137089085906323b872dd60e01b906084016139ae565b6000613ec86131fa565b9050806102fe5411613ed75750565b6000816102fe54613ee89190615975565b9050806102fe6000828254613efd9190615975565b90915550506102fb546119bf906001600160a01b03168261139a6102c6546001600160a01b031690565b613f2f613515565b60008111613f655760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fd19190615a79565b10156140055760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118ee6001600160a01b0382163384613982565b6102935460ff1615614029575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603614057575050565b6001600160a01b0380831660009081526102916020526040902054168015614083576118ee8183614019565b600061408f84846142ab565b905080156140e557610293805460ff1916600117905560006140b18583614c43565b610293805460ff191690559050806140e3576001600160a01b038516600090815261028f602052604090206003018290555b505b61370884614c9a565b60003330810361414c5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c654614165906001600160a01b0316823086613e86565b610cc98484613d42565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156141af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d39190615bae565b60ff1692915050565b6000600382101561420e576141f2826006615975565b6141fd90600a615cb5565b6142079084615b0d565b9050610ccf565b611087836103e8615b0d565b6000600382101561423157614207836103e8615b0d565b61423c82600a615cb5565b6110879084615b0d565b6000600382101561425e5761420783620f4240615b0d565b6142698260036158d4565b61423c90600a615cb5565b6000600382101561429f5761428a826006615975565b61429590600a615cb5565b61420790846158fd565b6110876103e8846158fd565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161431c85614dfc565b82515190915064ffffffffff161580614333575080155b1561434357600092505050610ccf565b815160200151604051630b27cfb160e31b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d889061438790610290908690600401615cc1565b6040805180830381865af41580156143a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143c79190615ce5565b60405163038255fd60e11b8152610290600482015290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af415801561441d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144419190615d30565b90508460200151955073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5384836040518363ffffffff1660e01b8152600401614483929190615d5c565b602060405180830381865af41580156144a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144c49190615b8c565b6147d557604051633e1e5c5360e11b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a690614502908790600401615d90565b6040805180830381865af415801561451e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145429190615d30565b604051630b27cfb160e31b815290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d889061458390610290908690600401615cc1565b6040805180830381865af415801561459f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145c39190615ce5565b875151602082015186519293506145f1928c6145e05760006145e2565b8b5b6145ec908b6158d4565b614ea5565b6145fb90896158d4565b97505b81945080935073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5386856040518363ffffffff1660e01b815260040161463d929190615d5c565b602060405180830381865af415801561465a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061467e9190615b8c565b6147a857604051633e1e5c5360e11b815273__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a6906146b9908890600401615d90565b6040805180830381865af41580156146d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f99190615d30565b604051630b27cfb160e31b815290925073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d889061473790610290908690600401615cc1565b6040805180830381865af4158015614753573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147779190615ce5565b90506147978460200151826020015186600001518c6145e05760006145e2565b6147a190896158d4565b97506145fe565b6147c284602001514286600001518c6145e05760006145e2565b6147cc90896158d4565b97505050614806565b84515182516147f9919042908a6147ed5760006147ef565b895b6145ec90896158d4565b61480390876158d4565b95505b505050505092915050565b600054610100900460ff166148385760405162461bcd60e51b8152600401610d1590615b41565b61484061489c565b61484983614f91565b614851614fc1565b61485a82614ff0565b6148638161503a565b6118ee61489c565b600054610100900460ff166148925760405162461bcd60e51b8152600401610d1590615b41565b6119bf8282615084565b600054610100900460ff166135745760405162461bcd60e51b8152600401610d1590615b41565b600054610100900460ff166148ea5760405162461bcd60e51b8152600401610d1590615b41565b306001600160a01b038216036149425760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6149708383836150c4565b6001600160a01b0383161561498a5761498a836001614019565b6001600160a01b038216156118ee576118ee826001614019565b6001600160a01b03831615806149c157506001600160a01b038216155b15614a01577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f6149ef61100c565b60405190815260200160405180910390a15b60005b61030254811015613708576103028181548110614a2357614a236158e7565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b158015614a8257600080fd5b505af1158015614a96573d6000803e3d6000fd5b505050508080614aa5906159ac565b915050614a04565b6000614b02826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166151259092919063ffffffff16565b9050805160001480614b23575080806020019051810190614b239190615b8c565b6118ee5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614bef5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615ef583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614c2783615134565b600082511180614c345750805b156118ee576137088383615174565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614c7985612572565b60408051918252602082018690520160405180910390a2613d398383613d42565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b8152610290600482015273__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af4158015614d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d3c9190615d30565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b038216600090815261029260205260409020548110156119bf576001600160a01b0382166000908152610292602052604090208054614dea919083908110614dd057614dd06158e7565b6000918252602090912001546001600160a01b0316614c9a565b80614df4816159ac565b915050614d7f565b6000614e0782615199565b614e1190826158d4565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e9f576001600160a01b0383166000908152610292602052604090208054614e81919083908110614e6757614e676158e7565b6000918252602090912001546001600160a01b0316614dfc565b614e8b90836158d4565b915080614e97816159ac565b915050614e16565b50919050565b600080614ebe61302661028e546001600160a01b031690565b90506000614edc614ecf8888615dad565b64ffffffffff1683614246565b90506000614eee6301e1338084614246565b614ef9600185614246565b614f039084615b0d565b614f0d91906158fd565b90506000614f1f8761ffff168561421a565b90506000614f2e600186614246565b614f388385615b0d565b614f4291906158fd565b90506000614f5088876141dc565b90506000614f5f606488614246565b614f698484615b0d565b614f7391906158fd565b9050614f7f8188614274565b9750505050505050505b949350505050565b600054610100900460ff16614fb85760405162461bcd60e51b8152600401610d1590615b41565b611534816151a4565b600054610100900460ff16614fe85760405162461bcd60e51b8152600401610d1590615b41565b6135746151ee565b600054610100900460ff166150175760405162461bcd60e51b8152600401610d1590615b41565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150615760405162461bcd60e51b8152600401610d1590615b41565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166150ab5760405162461bcd60e51b8152600401610d1590615b41565b609a6150b78382615e18565b50609b6118ee8282615e18565b6150cc6138ca565b826150d681613912565b156150f35760405162461bcd60e51b8152600401610d1590615a5d565b826150fd81613912565b1561511a5760405162461bcd60e51b8152600401610d1590615a5d565b6120cd858585615221565b6060614f898484600085615289565b61513d81614b82565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615f1560279139615364565b6000610ccf82612572565b600054610100900460ff166151cb5760405162461bcd60e51b8152600401610d1590615b41565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166152155760405162461bcd60e51b8152600401610d1590615b41565b60c9805460ff19169055565b615229611ab2565b156118ee5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152ea5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516153069190615ed8565b60006040518083038185875af1925050503d8060008114615343576040519150601f19603f3d011682016040523d82523d6000602084013e615348565b606091505b5091509150615359878383876153dc565b979650505050505050565b6060600080856001600160a01b0316856040516153819190615ed8565b600060405180830381855af49150503d80600081146153bc576040519150601f19603f3d011682016040523d82523d6000602084013e6153c1565b606091505b50915091506153d2868383876153dc565b9695505050505050565b6060831561544b578251600003615444576001600160a01b0385163b6154445760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614f89565b614f8983838151156154605781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061549e565b60005b8381101561549557818101518382015260200161547d565b50506000910152565b60208152600082518060208401526154bd81604085016020870161547a565b601f01601f19169190910160400192915050565b6001600160a01b038116811461153457600080fd5b600080604083850312156154f957600080fd5b8235615504816154d1565b946020939093013593505050565b60006020828403121561552457600080fd5b8135611087816154d1565b600080600080600060a0868803121561554757600080fd5b8535615552816154d1565b94506020860135615562816154d1565b93506040860135615572816154d1565b92506060860135615582816154d1565b91506080860135615592816154d1565b809150509295509295909350565b6000806000606084860312156155b557600080fd5b83356155c0816154d1565b925060208401356155d0816154d1565b929592945050506040919091013590565b6000602082840312156155f357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715615633576156336155fa565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715615662576156626155fa565b604052919050565b600067ffffffffffffffff821115615684576156846155fa565b50601f01601f191660200190565b600080604083850312156156a557600080fd5b82356156b0816154d1565b9150602083013567ffffffffffffffff8111156156cc57600080fd5b8301601f810185136156dd57600080fd5b80356156f06156eb8261566a565b615639565b81815286602083850101111561570557600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff8116811461153457600080fd5b60006020828403121561574757600080fd5b813561108781615725565b6000806040838503121561576557600080fd5b8235615770816154d1565b91506020830135615780816154d1565b809150509250929050565b63ffffffff8116811461153457600080fd5b6000602082840312156157af57600080fd5b81356110878161578b565b600181811c908216806157ce57607f821691505b602082108103614e9f57634e487b7160e01b600052602260045260246000fd5b60006020828403121561580057600080fd5b815167ffffffffffffffff81111561581757600080fd5b8201601f8101841361582857600080fd5b80516158366156eb8261566a565b81815285602083850101111561584b57600080fd5b61585c82602083016020860161547a565b95945050505050565b6702632b233b4ba3c960c51b81526000825161588881600885016020870161547a565b9190910160080192915050565b601360fa1b8152600082516158b181600185016020870161547a565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf6158be565b634e487b7160e01b600052603260045260246000fd5b60008261591a57634e487b7160e01b600052601260045260246000fd5b500490565b6004811061593d57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b0385811682528416602082015260808101615966604083018561591f565b82606083015295945050505050565b81810381811115610ccf57610ccf6158be565b6001600160601b03851681526020810184905260808101615966604083018561591f565b6000600182016159be576159be6158be565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b600060208284031215615a8b57600080fd5b5051919050565b8481526020810184905260808101615966604083018561591f565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615ad557600080fd5b8151611087816154d1565b600081615aef57615aef6158be565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf6158be565b600060208284031215615b3657600080fd5b815161108781615725565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615b9e57600080fd5b8151801515811461108757600080fd5b600060208284031215615bc057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615c0c578160001904821115615bf257615bf26158be565b80851615615bff57918102915b93841c9390800290615bd6565b509250929050565b600082615c2357506001610ccf565b81615c3057506000610ccf565b8160018114615c465760028114615c5057615c6c565b6001915050610ccf565b60ff841115615c6157615c616158be565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615c8f575081810a610ccf565b615c998383615bd1565b8060001904821115615cad57615cad6158be565b029392505050565b60006110878383615c14565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615cf757600080fd5b615cff615610565b8251615d0a81615725565b8152602083015164ffffffffff81168114615d2457600080fd5b60208201529392505050565b600060408284031215615d4257600080fd5b615d4a615610565b825181526020830151615d248161578b565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615dcb57615dcb6158be565b5092915050565b601f8211156118ee57600081815260208120601f850160051c81016020861015615df95750805b601f850160051c820191505b8181101561100457828155600101615e05565b815167ffffffffffffffff811115615e3257615e326155fa565b615e4681615e4084546157ba565b84615dd2565b602080601f831160018114615e7b5760008415615e635750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615eaa57888601518255948401946001909101908401615e8b565b5085821015615ec85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615eea81846020870161547a565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564d58e94604d90293a1c1ad95bfe6a6e6c352c33c5774a4b6b4f4b6f7460da29c5a264697066735822122075fca9467f2456a5739b6b2931262fe9508bbdbfb6838b51523f93bfbd0daa9764736f6c63430008120033", "libraries": { "APRHistory": "0x0165878A594ca255338adfa4d48449f69242Eb8F" }, @@ -1343,7 +1343,7 @@ "author": "Lila Rest (https://lila.rest)", "custom:oz-upgrades-unsafe-allow": "external-library-linking", "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", - "details": "Definitions: - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio). - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees). - Instant: Processed immediately. - Requested: Queued for later processing. - Big Requested: A requested withdrawal exceeding half of the retention rate. - (Withdrawal) queue: An list of all requested withdrawals sorted by priority. - Request ID: The index of a withdrawal request in the queue array. - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain. - Fees Rate: Percentage of fees applied to successful withdrawals. - Usable underlyings: Amount of underlying tokens that have been deposited through expected ways and are so considered as safe to use by the contract. - Transfers listeners: External contracts listening on L-Tokens transfers. - Fund wallet: Wallet managed by the Ledgity's financial team. - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request processing. Note that words between parenthesis are sometimes omitted for brevity.Security: This contract can safely receive funds immediately after initialization. (i.e., there is no way for funds to be sent to non-owned addresses). It is however recommended to replace ASAP owner and fund wallets by multi-sig wallets.For further details, see \"LToken\" section of whitepaper.", + "details": "Definitions: - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio). - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees). - Instant: Processed immediately. - Request: Queued for later processing. - Big Request: A requested withdrawal exceeding half of the retention rate. - (Withdrawal) queue: A list of all requested withdrawals sorted by priority. - Request ID: The index of a withdrawal request in the queue array. - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain. - Fees Rate: Percentage of fees applied to successful withdrawals. - Usable underlyings: Amount of underlying tokens that have been deposited through expected ways and are so considered safe to use by the contract. - Transfers listeners: External contracts listening on L-Tokens transfers. - Fund wallet: Wallet managed by the Ledgity's financial team. - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request processing. Note that words between parenthesis are sometimes omitted for brevity.Deployment notice: This contract can safely receive funds immediately after initialization. (i.e., there is no way for funds to be sent to non-owned addresses). It is, however, recommended to replace ASAP owner and fund wallets with multi-sig wallets.For further details, see \"LToken\" section of whitepaper.", "events": { "APRChangeEvent(uint16)": { "params": { @@ -1833,7 +1833,7 @@ "notice": "Holds address of withdrawer wallet (managed by withdrawal server)." } }, - "notice": "Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e, investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin. As soon as a wallet holds some L-Tokens, it starts receiving rewards in the form of additional L-Tokens, which are auto-compounded over time.", + "notice": "Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e., investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin. As soon as a wallet holds some L-Tokens, it starts receiving rewards in the form of additional L-Tokens, which are auto-compounded over time.", "version": 1 }, "storageLayout": { @@ -1959,15 +1959,15 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7671, + "astId": 6980, "contract": "contracts/src/LToken.sol:LToken", "label": "_globalOwner", "offset": 0, "slot": "301", - "type": "t_contract(GlobalOwner)4909" + "type": "t_contract(GlobalOwner)4271" }, { - "astId": 7755, + "astId": 7064, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -1975,15 +1975,15 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 7773, + "astId": 7082, "contract": "contracts/src/LToken.sol:LToken", "label": "_globalPause", "offset": 0, "slot": "352", - "type": "t_contract(GlobalPause)4985" + "type": "t_contract(GlobalPause)4347" }, { - "astId": 7832, + "astId": 7141, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -1991,15 +1991,15 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 7846, + "astId": 7155, "contract": "contracts/src/LToken.sol:LToken", "label": "_globalBlacklist", "offset": 0, "slot": "403", - "type": "t_contract(GlobalBlacklist)4862" + "type": "t_contract(GlobalBlacklist)4224" }, { - "astId": 7920, + "astId": 7229, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -2007,7 +2007,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 8939, + "astId": 8248, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -2015,7 +2015,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 9030, + "astId": 8339, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -2031,7 +2031,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 9135, + "astId": 8444, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -2039,7 +2039,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 7972, + "astId": 7281, "contract": "contracts/src/LToken.sol:LToken", "label": "_invested", "offset": 0, @@ -2047,23 +2047,23 @@ "type": "t_contract(IERC20Upgradeable)1724" }, { - "astId": 7978, + "astId": 7287, "contract": "contracts/src/LToken.sol:LToken", "label": "accountsDetails", "offset": 0, "slot": "655", - "type": "t_mapping(t_address,t_struct(AccountDetails)7968_storage)" + "type": "t_mapping(t_address,t_struct(AccountDetails)7277_storage)" }, { - "astId": 7983, + "astId": 7292, "contract": "contracts/src/LToken.sol:LToken", "label": "_aprHistory", "offset": 0, "slot": "656", - "type": "t_array(t_struct(Pack)12534_storage)dyn_storage" + "type": "t_array(t_struct(Pack)8476_storage)dyn_storage" }, { - "astId": 7988, + "astId": 7297, "contract": "contracts/src/LToken.sol:LToken", "label": "rewardsRedirectsFromTo", "offset": 0, @@ -2071,7 +2071,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 7993, + "astId": 7302, "contract": "contracts/src/LToken.sol:LToken", "label": "rewardsRedirectsToFrom", "offset": 0, @@ -2079,7 +2079,7 @@ "type": "t_mapping(t_address,t_array(t_address)dyn_storage)" }, { - "astId": 7996, + "astId": 7305, "contract": "contracts/src/LToken.sol:LToken", "label": "_isClaiming", "offset": 0, @@ -2087,7 +2087,7 @@ "type": "t_bool" }, { - "astId": 8846, + "astId": 8155, "contract": "contracts/src/LToken.sol:LToken", "label": "__gap", "offset": 0, @@ -2111,15 +2111,15 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 5045, + "astId": 4415, "contract": "contracts/src/LToken.sol:LToken", "label": "ldyStaking", "offset": 0, "slot": "761", - "type": "t_contract(LDYStaking)4745" + "type": "t_contract(LDYStaking)4089" }, { - "astId": 5048, + "astId": 4418, "contract": "contracts/src/LToken.sol:LToken", "label": "withdrawer", "offset": 0, @@ -2127,7 +2127,7 @@ "type": "t_address_payable" }, { - "astId": 5051, + "astId": 4421, "contract": "contracts/src/LToken.sol:LToken", "label": "fund", "offset": 0, @@ -2135,7 +2135,7 @@ "type": "t_address" }, { - "astId": 5054, + "astId": 4424, "contract": "contracts/src/LToken.sol:LToken", "label": "feesRateUD7x3", "offset": 20, @@ -2143,7 +2143,7 @@ "type": "t_uint32" }, { - "astId": 5057, + "astId": 4427, "contract": "contracts/src/LToken.sol:LToken", "label": "retentionRateUD7x3", "offset": 24, @@ -2151,7 +2151,7 @@ "type": "t_uint32" }, { - "astId": 5060, + "astId": 4430, "contract": "contracts/src/LToken.sol:LToken", "label": "unclaimedFees", "offset": 0, @@ -2159,7 +2159,7 @@ "type": "t_uint256" }, { - "astId": 5063, + "astId": 4433, "contract": "contracts/src/LToken.sol:LToken", "label": "totalQueued", "offset": 0, @@ -2167,7 +2167,7 @@ "type": "t_uint256" }, { - "astId": 5066, + "astId": 4436, "contract": "contracts/src/LToken.sol:LToken", "label": "usableUnderlyings", "offset": 0, @@ -2175,15 +2175,15 @@ "type": "t_uint256" }, { - "astId": 5071, + "astId": 4441, "contract": "contracts/src/LToken.sol:LToken", "label": "withdrawalQueue", "offset": 0, "slot": "767", - "type": "t_array(t_struct(WithdrawalRequest)5028_storage)dyn_storage" + "type": "t_array(t_struct(WithdrawalRequest)4390_storage)dyn_storage" }, { - "astId": 5074, + "astId": 4444, "contract": "contracts/src/LToken.sol:LToken", "label": "withdrawalQueueCursor", "offset": 0, @@ -2191,20 +2191,20 @@ "type": "t_uint256" }, { - "astId": 5079, + "astId": 4449, "contract": "contracts/src/LToken.sol:LToken", "label": "frozenRequests", "offset": 0, "slot": "769", - "type": "t_array(t_struct(WithdrawalRequest)5028_storage)dyn_storage" + "type": "t_array(t_struct(WithdrawalRequest)4390_storage)dyn_storage" }, { - "astId": 5084, + "astId": 4454, "contract": "contracts/src/LToken.sol:LToken", "label": "transfersListeners", "offset": 0, "slot": "770", - "type": "t_array(t_contract(ITransfersListener)12515)dyn_storage" + "type": "t_array(t_contract(ITransfersListener)8457)dyn_storage" } ], "types": { @@ -2224,20 +2224,20 @@ "label": "address[]", "numberOfBytes": "32" }, - "t_array(t_contract(ITransfersListener)12515)dyn_storage": { - "base": "t_contract(ITransfersListener)12515", + "t_array(t_contract(ITransfersListener)8457)dyn_storage": { + "base": "t_contract(ITransfersListener)8457", "encoding": "dynamic_array", "label": "contract ITransfersListener[]", "numberOfBytes": "32" }, - "t_array(t_struct(Pack)12534_storage)dyn_storage": { - "base": "t_struct(Pack)12534_storage", + "t_array(t_struct(Pack)8476_storage)dyn_storage": { + "base": "t_struct(Pack)8476_storage", "encoding": "dynamic_array", "label": "struct APRHistory.Pack[]", "numberOfBytes": "32" }, - "t_array(t_struct(WithdrawalRequest)5028_storage)dyn_storage": { - "base": "t_struct(WithdrawalRequest)5028_storage", + "t_array(t_struct(WithdrawalRequest)4390_storage)dyn_storage": { + "base": "t_struct(WithdrawalRequest)4390_storage", "encoding": "dynamic_array", "label": "struct LToken.WithdrawalRequest[]", "numberOfBytes": "32" @@ -2277,17 +2277,17 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(GlobalBlacklist)4862": { + "t_contract(GlobalBlacklist)4224": { "encoding": "inplace", "label": "contract GlobalBlacklist", "numberOfBytes": "20" }, - "t_contract(GlobalOwner)4909": { + "t_contract(GlobalOwner)4271": { "encoding": "inplace", "label": "contract GlobalOwner", "numberOfBytes": "20" }, - "t_contract(GlobalPause)4985": { + "t_contract(GlobalPause)4347": { "encoding": "inplace", "label": "contract GlobalPause", "numberOfBytes": "20" @@ -2297,12 +2297,12 @@ "label": "contract IERC20Upgradeable", "numberOfBytes": "20" }, - "t_contract(ITransfersListener)12515": { + "t_contract(ITransfersListener)8457": { "encoding": "inplace", "label": "contract ITransfersListener", "numberOfBytes": "20" }, - "t_contract(LDYStaking)4745": { + "t_contract(LDYStaking)4089": { "encoding": "inplace", "label": "contract LDYStaking", "numberOfBytes": "20" @@ -2328,12 +2328,12 @@ "numberOfBytes": "32", "value": "t_mapping(t_address,t_uint256)" }, - "t_mapping(t_address,t_struct(AccountDetails)7968_storage)": { + "t_mapping(t_address,t_struct(AccountDetails)7277_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct InvestUpgradeable.AccountDetails)", "numberOfBytes": "32", - "value": "t_struct(AccountDetails)7968_storage" + "value": "t_struct(AccountDetails)7277_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -2347,20 +2347,20 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(AccountDetails)7968_storage": { + "t_struct(AccountDetails)7277_storage": { "encoding": "inplace", "label": "struct InvestUpgradeable.AccountDetails", "members": [ { - "astId": 7965, + "astId": 7274, "contract": "contracts/src/LToken.sol:LToken", "label": "period", "offset": 0, "slot": "0", - "type": "t_struct(InvestmentPeriod)7962_storage" + "type": "t_struct(InvestmentPeriod)7271_storage" }, { - "astId": 7967, + "astId": 7276, "contract": "contracts/src/LToken.sol:LToken", "label": "virtualBalance", "offset": 0, @@ -2370,12 +2370,12 @@ ], "numberOfBytes": "128" }, - "t_struct(InvestmentPeriod)7962_storage": { + "t_struct(InvestmentPeriod)7271_storage": { "encoding": "inplace", "label": "struct InvestUpgradeable.InvestmentPeriod", "members": [ { - "astId": 7958, + "astId": 7267, "contract": "contracts/src/LToken.sol:LToken", "label": "timestamp", "offset": 0, @@ -2383,22 +2383,22 @@ "type": "t_uint40" }, { - "astId": 7961, + "astId": 7270, "contract": "contracts/src/LToken.sol:LToken", "label": "ref", "offset": 0, "slot": "1", - "type": "t_struct(Reference)12539_storage" + "type": "t_struct(Reference)8481_storage" } ], "numberOfBytes": "96" }, - "t_struct(Pack)12534_storage": { + "t_struct(Pack)8476_storage": { "encoding": "inplace", "label": "struct APRHistory.Pack", "members": [ { - "astId": 12527, + "astId": 8469, "contract": "contracts/src/LToken.sol:LToken", "label": "aprsUD7x3", "offset": 0, @@ -2406,7 +2406,7 @@ "type": "t_array(t_uint16)4_storage" }, { - "astId": 12531, + "astId": 8473, "contract": "contracts/src/LToken.sol:LToken", "label": "timestamps", "offset": 0, @@ -2414,7 +2414,7 @@ "type": "t_array(t_uint40)4_storage" }, { - "astId": 12533, + "astId": 8475, "contract": "contracts/src/LToken.sol:LToken", "label": "cursor", "offset": 0, @@ -2424,12 +2424,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Reference)12539_storage": { + "t_struct(Reference)8481_storage": { "encoding": "inplace", "label": "struct APRHistory.Reference", "members": [ { - "astId": 12536, + "astId": 8478, "contract": "contracts/src/LToken.sol:LToken", "label": "packIndex", "offset": 0, @@ -2437,7 +2437,7 @@ "type": "t_uint256" }, { - "astId": 12538, + "astId": 8480, "contract": "contracts/src/LToken.sol:LToken", "label": "cursorIndex", "offset": 0, @@ -2447,12 +2447,12 @@ ], "numberOfBytes": "64" }, - "t_struct(WithdrawalRequest)5028_storage": { + "t_struct(WithdrawalRequest)4390_storage": { "encoding": "inplace", "label": "struct LToken.WithdrawalRequest", "members": [ { - "astId": 5025, + "astId": 4387, "contract": "contracts/src/LToken.sol:LToken", "label": "account", "offset": 0, @@ -2460,7 +2460,7 @@ "type": "t_address" }, { - "astId": 5027, + "astId": 4389, "contract": "contracts/src/LToken.sol:LToken", "label": "amount", "offset": 20, diff --git a/contracts/hardhat/deployments/localhost/LUSDC_Proxy.json b/contracts/hardhat/deployments/localhost/LUSDC_Proxy.json index 8b0ab55e..a2782b28 100644 --- a/contracts/hardhat/deployments/localhost/LUSDC_Proxy.json +++ b/contracts/hardhat/deployments/localhost/LUSDC_Proxy.json @@ -79,7 +79,7 @@ "transactionIndex": 0, "gasUsed": "652222", "logsBloom": "0x0000000000000000000000000000000040000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000400000000000000001000000000000000000000000000", - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322", + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132", "transactionHash": "0xec1c869bf0e186536e1800b5313b9282c47faf42885f2c0b8d4c9d6bdf7f67d8", "logs": [ { @@ -93,7 +93,7 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322" + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132" }, { "transactionIndex": 0, @@ -105,7 +105,7 @@ ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 1, - "blockHash": "0xbdc3ce711c983a3946d8e98699f500bc18de46a045112c63720c7a5cfc347322" + "blockHash": "0x1660a821e1683ddc6d2e7b0a50b2d95ddd88cbb25a73c438e46d222f70cb8132" } ], "blockNumber": 11, diff --git a/contracts/hardhat/deployments/localhost/Multicall3.json b/contracts/hardhat/deployments/localhost/Multicall3.json deleted file mode 100644 index 0e81f23c..00000000 --- a/contracts/hardhat/deployments/localhost/Multicall3.json +++ /dev/null @@ -1,592 +0,0 @@ -{ - "address": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", - "abi": [ - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "aggregate", - "outputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "internalType": "bytes[]", - "name": "returnData", - "type": "bytes[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bool", - "name": "allowFailure", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call3[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "aggregate3", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Result[]", - "name": "returnData", - "type": "tuple[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bool", - "name": "allowFailure", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call3Value[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "aggregate3Value", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Result[]", - "name": "returnData", - "type": "tuple[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "blockAndAggregate", - "outputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Result[]", - "name": "returnData", - "type": "tuple[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "getBasefee", - "outputs": [ - { - "internalType": "uint256", - "name": "basefee", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - } - ], - "name": "getBlockHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getChainId", - "outputs": [ - { - "internalType": "uint256", - "name": "chainid", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockCoinbase", - "outputs": [ - { - "internalType": "address", - "name": "coinbase", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockDifficulty", - "outputs": [ - { - "internalType": "uint256", - "name": "difficulty", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockGasLimit", - "outputs": [ - { - "internalType": "uint256", - "name": "gaslimit", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "getEthBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getLastBlockHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "requireSuccess", - "type": "bool" - }, - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "tryAggregate", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Result[]", - "name": "returnData", - "type": "tuple[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "requireSuccess", - "type": "bool" - }, - { - "components": [ - { - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Call[]", - "name": "calls", - "type": "tuple[]" - } - ], - "name": "tryBlockAndAggregate", - "outputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "blockHash", - "type": "bytes32" - }, - { - "components": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "internalType": "struct Multicall3.Result[]", - "name": "returnData", - "type": "tuple[]" - } - ], - "stateMutability": "payable", - "type": "function" - } - ], - "transactionHash": "0xf461997b5ef7e104520903b33178790dbe513172b64e8f2f480d4e65ddbd7025", - "receipt": { - "to": null, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", - "transactionIndex": 0, - "gasUsed": "761389", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcfc905f07fd55ba0840c3055aa551df7895a4dd700e80ddd35a6967f72f258b4", - "transactionHash": "0xf461997b5ef7e104520903b33178790dbe513172b64e8f2f480d4e65ddbd7025", - "logs": [], - "blockNumber": 14, - "cumulativeGasUsed": "761389", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Multicall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon \",\"details\":\"Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call\",\"kind\":\"dev\",\"methods\":{\"aggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of bytes containing the responses\"}},\"aggregate3((address,bool,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3 structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"params\":{\"calls\":\"An array of Call3Value structs\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"blockAndAggregate((address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}},\"getBlockHash(uint256)\":{\"params\":{\"blockNumber\":\"The block number\"}},\"tryAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\",\"requireSuccess\":\"If true, require all calls to succeed\"},\"returns\":{\"returnData\":\"An array of Result structs\"}},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"params\":{\"calls\":\"An array of Call structs\"},\"returns\":{\"blockHash\":\"The hash of the block where the calls were executed\",\"blockNumber\":\"The block number where the calls were executed\",\"returnData\":\"An array of Result structs\"}}},\"title\":\"Multicall3\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"aggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible call aggregation with Multicall\"},\"aggregate3((address,bool,bytes)[])\":{\"notice\":\"Aggregate calls, ensuring each returns success if required\"},\"aggregate3Value((address,bool,uint256,bytes)[])\":{\"notice\":\"Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values\"},\"blockAndAggregate((address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"},\"getBasefee()\":{\"notice\":\"Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain\"},\"getBlockHash(uint256)\":{\"notice\":\"Returns the block hash for the given block number\"},\"getBlockNumber()\":{\"notice\":\"Returns the block number\"},\"getChainId()\":{\"notice\":\"Returns the chain id\"},\"getCurrentBlockCoinbase()\":{\"notice\":\"Returns the block coinbase\"},\"getCurrentBlockDifficulty()\":{\"notice\":\"Returns the block difficulty\"},\"getCurrentBlockGasLimit()\":{\"notice\":\"Returns the block gas limit\"},\"getCurrentBlockTimestamp()\":{\"notice\":\"Returns the block timestamp\"},\"getEthBalance(address)\":{\"notice\":\"Returns the (ETH) balance of a given address\"},\"getLastBlockHash()\":{\"notice\":\"Returns the block hash of the last block\"},\"tryAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls without requiring success\"},\"tryBlockAndAggregate(bool,(address,bytes)[])\":{\"notice\":\"Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate\"}},\"notice\":\"Aggregate results from multiple function calls\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/dev/Multicall3.sol\":\"Multicall3\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/src/dev/Multicall3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title Multicall3\\n/// @notice Aggregate results from multiple function calls\\n/// @dev Multicall & Multicall2 backwards-compatible\\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\\n/// @author Michael Elliot \\n/// @author Joshua Levine \\n/// @author Nick Johnson \\n/// @author Andreas Bigger \\n/// @author Matt Solomon \\ncontract Multicall3 {\\n struct Call {\\n address target;\\n bytes callData;\\n }\\n\\n struct Call3 {\\n address target;\\n bool allowFailure;\\n bytes callData;\\n }\\n\\n struct Call3Value {\\n address target;\\n bool allowFailure;\\n uint256 value;\\n bytes callData;\\n }\\n\\n struct Result {\\n bool success;\\n bytes returnData;\\n }\\n\\n /// @notice Backwards-compatible call aggregation with Multicall\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return returnData An array of bytes containing the responses\\n function aggregate(\\n Call[] calldata calls\\n ) public payable returns (uint256 blockNumber, bytes[] memory returnData) {\\n blockNumber = block.number;\\n uint256 length = calls.length;\\n returnData = new bytes[](length);\\n Call calldata call;\\n for (uint256 i = 0; i < length; ) {\\n bool success;\\n call = calls[i];\\n (success, returnData[i]) = call.target.call(call.callData);\\n require(success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls without requiring success\\n /// @param requireSuccess If true, require all calls to succeed\\n /// @param calls An array of Call structs\\n /// @return returnData An array of Result structs\\n function tryAggregate(\\n bool requireSuccess,\\n Call[] calldata calls\\n ) public payable returns (Result[] memory returnData) {\\n uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call calldata call;\\n for (uint256 i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n call = calls[i];\\n (result.success, result.returnData) = call.target.call(call.callData);\\n if (requireSuccess) require(result.success, \\\"Multicall3: call failed\\\");\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function tryBlockAndAggregate(\\n bool requireSuccess,\\n Call[] calldata calls\\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\\n blockNumber = block.number;\\n blockHash = blockhash(block.number);\\n returnData = tryAggregate(requireSuccess, calls);\\n }\\n\\n /// @notice Backwards-compatible with Multicall2\\n /// @notice Aggregate calls and allow failures using tryAggregate\\n /// @param calls An array of Call structs\\n /// @return blockNumber The block number where the calls were executed\\n /// @return blockHash The hash of the block where the calls were executed\\n /// @return returnData An array of Result structs\\n function blockAndAggregate(\\n Call[] calldata calls\\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\\n }\\n\\n /// @notice Aggregate calls, ensuring each returns success if required\\n /// @param calls An array of Call3 structs\\n /// @return returnData An array of Result structs\\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\\n uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call3 calldata calli;\\n for (uint256 i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n (result.success, result.returnData) = calli.target.call(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x64)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Aggregate calls with a msg value\\n /// @notice Reverts if msg.value is less than the sum of the call values\\n /// @param calls An array of Call3Value structs\\n /// @return returnData An array of Result structs\\n function aggregate3Value(\\n Call3Value[] calldata calls\\n ) public payable returns (Result[] memory returnData) {\\n uint256 valAccumulator;\\n uint256 length = calls.length;\\n returnData = new Result[](length);\\n Call3Value calldata calli;\\n for (uint256 i = 0; i < length; ) {\\n Result memory result = returnData[i];\\n calli = calls[i];\\n uint256 val = calli.value;\\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\\n unchecked {\\n valAccumulator += val;\\n }\\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\\n assembly {\\n // Revert if the call fails and failure is not allowed\\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\\n // set \\\"Error(string)\\\" signature: bytes32(bytes4(keccak256(\\\"Error(string)\\\")))\\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\\n // set data offset\\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\\n // set length of revert string\\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\\n // set revert string: bytes32(abi.encodePacked(\\\"Multicall3: call failed\\\"))\\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\\n revert(0x00, 0x84)\\n }\\n }\\n unchecked {\\n ++i;\\n }\\n }\\n // Finally, make sure the msg.value = SUM(call[0...i].value)\\n require(msg.value == valAccumulator, \\\"Multicall3: value mismatch\\\");\\n }\\n\\n /// @notice Returns the block hash for the given block number\\n /// @param blockNumber The block number\\n function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {\\n blockHash = blockhash(blockNumber);\\n }\\n\\n /// @notice Returns the block number\\n function getBlockNumber() public view returns (uint256 blockNumber) {\\n blockNumber = block.number;\\n }\\n\\n /// @notice Returns the block coinbase\\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\\n coinbase = block.coinbase;\\n }\\n\\n /// @notice Returns the block difficulty\\n function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {\\n difficulty = block.difficulty;\\n }\\n\\n /// @notice Returns the block gas limit\\n function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {\\n gaslimit = block.gaslimit;\\n }\\n\\n /// @notice Returns the block timestamp\\n function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {\\n timestamp = block.timestamp;\\n }\\n\\n /// @notice Returns the (ETH) balance of a given address\\n function getEthBalance(address addr) public view returns (uint256 balance) {\\n balance = addr.balance;\\n }\\n\\n /// @notice Returns the block hash of the last block\\n function getLastBlockHash() public view returns (bytes32 blockHash) {\\n unchecked {\\n blockHash = blockhash(block.number - 1);\\n }\\n }\\n\\n /// @notice Gets the base fee of the given block\\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\\n function getBasefee() public view returns (uint256 basefee) {\\n basefee = block.basefee;\\n }\\n\\n /// @notice Returns the chain id\\n function getChainId() public view returns (uint256 chainid) {\\n chainid = block.chainid;\\n }\\n}\\n\",\"keccak256\":\"0x17297b5a1a76e95335eccbe1b05797471948677d0c81b84bae5ed1138585a806\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50610ccf806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461022f578063bce38bd71461024a578063c3077fa91461025d578063ee82ac5e1461027057600080fd5b80634d2301cc146101ce57806372425d9d146101f657806382ad56cb1461020957806386d516e81461021c57600080fd5b80633408e470116100c65780633408e47014610173578063399542e9146101865780633e64a696146101a857806342cbb15c146101bb57600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d61012836600461098c565b61028f565b6040516101119190610a82565b61014d61014836600461098c565b61047d565b604051610111929190610a9c565b34801561016757600080fd5b50436000190140610107565b34801561017f57600080fd5b5046610107565b610199610194366004610b06565b6105f1565b60405161011193929190610b60565b3480156101b457600080fd5b5048610107565b3480156101c757600080fd5b5043610107565b3480156101da57600080fd5b506101076101e9366004610b88565b6001600160a01b03163190565b34801561020257600080fd5b5044610107565b61012d61021736600461098c565b61060c565b34801561022857600080fd5b5045610107565b34801561023b57600080fd5b50604051418152602001610111565b61012d610258366004610b06565b61078e565b61019961026b36600461098c565b610921565b34801561027c57600080fd5b5061010761028b366004610bb1565b4090565b60606000828067ffffffffffffffff8111156102ad576102ad610bca565b6040519080825280602002602001820160405280156102f357816020015b6040805180820190915260008152606060208201528152602001906001900390816102cb5790505b5092503660005b8281101561041f57600085828151811061031657610316610be0565b6020026020010151905087878381811061033257610332610be0565b90506020028101906103449190610bf6565b60408101359586019590935061035d6020850185610b88565b6001600160a01b0316816103746060870187610c16565b604051610382929190610c5d565b60006040518083038185875af1925050503d80600081146103bf576040519150601f19603f3d011682016040523d82523d6000602084013e6103c4565b606091505b5060208085019190915290151580845290850135176104155762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260846000fd5b50506001016102fa565b508234146104745760405162461bcd60e51b815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561049a5761049a610bca565b6040519080825280602002602001820160405280156104cd57816020015b60608152602001906001900390816104b85790505b5091503660005b828110156105e75760008787838181106104f0576104f0610be0565b90506020028101906105029190610c6d565b92506105116020840184610b88565b6001600160a01b03166105276020850185610c16565b604051610535929190610c5d565b6000604051808303816000865af19150503d8060008114610572576040519150601f19603f3d011682016040523d82523d6000602084013e610577565b606091505b5086848151811061058a5761058a610be0565b60209081029190910101529050806105de5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016104d4565b5050509250929050565b438040606061060186868661078e565b905093509350939050565b6060818067ffffffffffffffff81111561062857610628610bca565b60405190808252806020026020018201604052801561066e57816020015b6040805180820190915260008152606060208201528152602001906001900390816106465790505b5091503660005b8281101561047457600084828151811061069157610691610be0565b602002602001015190508686838181106106ad576106ad610be0565b90506020028101906106bf9190610c83565b92506106ce6020840184610b88565b6001600160a01b03166106e46040850185610c16565b6040516106f2929190610c5d565b6000604051808303816000865af19150503d806000811461072f576040519150601f19603f3d011682016040523d82523d6000602084013e610734565b606091505b5060208084019190915290151580835290840135176107855762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260646000fd5b50600101610675565b6060818067ffffffffffffffff8111156107aa576107aa610bca565b6040519080825280602002602001820160405280156107f057816020015b6040805180820190915260008152606060208201528152602001906001900390816107c85790505b5091503660005b8281101561091757600084828151811061081357610813610be0565b6020026020010151905086868381811061082f5761082f610be0565b90506020028101906108419190610c6d565b92506108506020840184610b88565b6001600160a01b03166108666020850185610c16565b604051610874929190610c5d565b6000604051808303816000865af19150503d80600081146108b1576040519150601f19603f3d011682016040523d82523d6000602084013e6108b6565b606091505b50602083015215158152871561090e57805161090e5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016107f7565b5050509392505050565b6000806060610932600186866105f1565b919790965090945092505050565b60008083601f84011261095257600080fd5b50813567ffffffffffffffff81111561096a57600080fd5b6020830191508360208260051b850101111561098557600080fd5b9250929050565b6000806020838503121561099f57600080fd5b823567ffffffffffffffff8111156109b657600080fd5b6109c285828601610940565b90969095509350505050565b6000815180845260005b818110156109f4576020818501810151868301820152016109d8565b506000602082860101526020601f19601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610a7557858303601f1901895281518051151584528401516040858501819052610a61818601836109ce565b9a86019a9450505090830190600101610a31565b5090979650505050505050565b602081526000610a956020830184610a14565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610af857605f19888703018452610ae68683516109ce565b95509284019290840190600101610aca565b509398975050505050505050565b600080600060408486031215610b1b57600080fd5b83358015158114610b2b57600080fd5b9250602084013567ffffffffffffffff811115610b4757600080fd5b610b5386828701610940565b9497909650939450505050565b838152826020820152606060408201526000610b7f6060830184610a14565b95945050505050565b600060208284031215610b9a57600080fd5b81356001600160a01b0381168114610a9557600080fd5b600060208284031215610bc357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610c0c57600080fd5b9190910192915050565b6000808335601e19843603018112610c2d57600080fd5b83018035915067ffffffffffffffff821115610c4857600080fd5b60200191503681900382131561098557600080fd5b8183823760009101908152919050565b60008235603e19833603018112610c0c57600080fd5b60008235605e19833603018112610c0c57600080fdfea2646970667358221220836504f3ba74e3f5f8b8853010523b1d0d295bc0b99a253bd16417233b7c65e564736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461022f578063bce38bd71461024a578063c3077fa91461025d578063ee82ac5e1461027057600080fd5b80634d2301cc146101ce57806372425d9d146101f657806382ad56cb1461020957806386d516e81461021c57600080fd5b80633408e470116100c65780633408e47014610173578063399542e9146101865780633e64a696146101a857806342cbb15c146101bb57600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d61012836600461098c565b61028f565b6040516101119190610a82565b61014d61014836600461098c565b61047d565b604051610111929190610a9c565b34801561016757600080fd5b50436000190140610107565b34801561017f57600080fd5b5046610107565b610199610194366004610b06565b6105f1565b60405161011193929190610b60565b3480156101b457600080fd5b5048610107565b3480156101c757600080fd5b5043610107565b3480156101da57600080fd5b506101076101e9366004610b88565b6001600160a01b03163190565b34801561020257600080fd5b5044610107565b61012d61021736600461098c565b61060c565b34801561022857600080fd5b5045610107565b34801561023b57600080fd5b50604051418152602001610111565b61012d610258366004610b06565b61078e565b61019961026b36600461098c565b610921565b34801561027c57600080fd5b5061010761028b366004610bb1565b4090565b60606000828067ffffffffffffffff8111156102ad576102ad610bca565b6040519080825280602002602001820160405280156102f357816020015b6040805180820190915260008152606060208201528152602001906001900390816102cb5790505b5092503660005b8281101561041f57600085828151811061031657610316610be0565b6020026020010151905087878381811061033257610332610be0565b90506020028101906103449190610bf6565b60408101359586019590935061035d6020850185610b88565b6001600160a01b0316816103746060870187610c16565b604051610382929190610c5d565b60006040518083038185875af1925050503d80600081146103bf576040519150601f19603f3d011682016040523d82523d6000602084013e6103c4565b606091505b5060208085019190915290151580845290850135176104155762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260846000fd5b50506001016102fa565b508234146104745760405162461bcd60e51b815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561049a5761049a610bca565b6040519080825280602002602001820160405280156104cd57816020015b60608152602001906001900390816104b85790505b5091503660005b828110156105e75760008787838181106104f0576104f0610be0565b90506020028101906105029190610c6d565b92506105116020840184610b88565b6001600160a01b03166105276020850185610c16565b604051610535929190610c5d565b6000604051808303816000865af19150503d8060008114610572576040519150601f19603f3d011682016040523d82523d6000602084013e610577565b606091505b5086848151811061058a5761058a610be0565b60209081029190910101529050806105de5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016104d4565b5050509250929050565b438040606061060186868661078e565b905093509350939050565b6060818067ffffffffffffffff81111561062857610628610bca565b60405190808252806020026020018201604052801561066e57816020015b6040805180820190915260008152606060208201528152602001906001900390816106465790505b5091503660005b8281101561047457600084828151811061069157610691610be0565b602002602001015190508686838181106106ad576106ad610be0565b90506020028101906106bf9190610c83565b92506106ce6020840184610b88565b6001600160a01b03166106e46040850185610c16565b6040516106f2929190610c5d565b6000604051808303816000865af19150503d806000811461072f576040519150601f19603f3d011682016040523d82523d6000602084013e610734565b606091505b5060208084019190915290151580835290840135176107855762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260646000fd5b50600101610675565b6060818067ffffffffffffffff8111156107aa576107aa610bca565b6040519080825280602002602001820160405280156107f057816020015b6040805180820190915260008152606060208201528152602001906001900390816107c85790505b5091503660005b8281101561091757600084828151811061081357610813610be0565b6020026020010151905086868381811061082f5761082f610be0565b90506020028101906108419190610c6d565b92506108506020840184610b88565b6001600160a01b03166108666020850185610c16565b604051610874929190610c5d565b6000604051808303816000865af19150503d80600081146108b1576040519150601f19603f3d011682016040523d82523d6000602084013e6108b6565b606091505b50602083015215158152871561090e57805161090e5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016107f7565b5050509392505050565b6000806060610932600186866105f1565b919790965090945092505050565b60008083601f84011261095257600080fd5b50813567ffffffffffffffff81111561096a57600080fd5b6020830191508360208260051b850101111561098557600080fd5b9250929050565b6000806020838503121561099f57600080fd5b823567ffffffffffffffff8111156109b657600080fd5b6109c285828601610940565b90969095509350505050565b6000815180845260005b818110156109f4576020818501810151868301820152016109d8565b506000602082860101526020601f19601f83011685010191505092915050565b600082825180855260208086019550808260051b84010181860160005b84811015610a7557858303601f1901895281518051151584528401516040858501819052610a61818601836109ce565b9a86019a9450505090830190600101610a31565b5090979650505050505050565b602081526000610a956020830184610a14565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610af857605f19888703018452610ae68683516109ce565b95509284019290840190600101610aca565b509398975050505050505050565b600080600060408486031215610b1b57600080fd5b83358015158114610b2b57600080fd5b9250602084013567ffffffffffffffff811115610b4757600080fd5b610b5386828701610940565b9497909650939450505050565b838152826020820152606060408201526000610b7f6060830184610a14565b95945050505050565b600060208284031215610b9a57600080fd5b81356001600160a01b0381168114610a9557600080fd5b600060208284031215610bc357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610c0c57600080fd5b9190910192915050565b6000808335601e19843603018112610c2d57600080fd5b83018035915067ffffffffffffffff821115610c4857600080fd5b60200191503681900382131561098557600080fd5b8183823760009101908152919050565b60008235603e19833603018112610c0c57600080fd5b60008235605e19833603018112610c0c57600080fdfea2646970667358221220836504f3ba74e3f5f8b8853010523b1d0d295bc0b99a253bd16417233b7c65e564736f6c63430008120033", - "devdoc": { - "author": "Michael Elliot Joshua Levine Nick Johnson Andreas Bigger Matt Solomon ", - "details": "Multicall & Multicall2 backwards-compatibleAggregate methods are marked `payable` to save 24 gas per call", - "kind": "dev", - "methods": { - "aggregate((address,bytes)[])": { - "params": { - "calls": "An array of Call structs" - }, - "returns": { - "blockNumber": "The block number where the calls were executed", - "returnData": "An array of bytes containing the responses" - } - }, - "aggregate3((address,bool,bytes)[])": { - "params": { - "calls": "An array of Call3 structs" - }, - "returns": { - "returnData": "An array of Result structs" - } - }, - "aggregate3Value((address,bool,uint256,bytes)[])": { - "params": { - "calls": "An array of Call3Value structs" - }, - "returns": { - "returnData": "An array of Result structs" - } - }, - "blockAndAggregate((address,bytes)[])": { - "params": { - "calls": "An array of Call structs" - }, - "returns": { - "blockHash": "The hash of the block where the calls were executed", - "blockNumber": "The block number where the calls were executed", - "returnData": "An array of Result structs" - } - }, - "getBlockHash(uint256)": { - "params": { - "blockNumber": "The block number" - } - }, - "tryAggregate(bool,(address,bytes)[])": { - "params": { - "calls": "An array of Call structs", - "requireSuccess": "If true, require all calls to succeed" - }, - "returns": { - "returnData": "An array of Result structs" - } - }, - "tryBlockAndAggregate(bool,(address,bytes)[])": { - "params": { - "calls": "An array of Call structs" - }, - "returns": { - "blockHash": "The hash of the block where the calls were executed", - "blockNumber": "The block number where the calls were executed", - "returnData": "An array of Result structs" - } - } - }, - "title": "Multicall3", - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "aggregate((address,bytes)[])": { - "notice": "Backwards-compatible call aggregation with Multicall" - }, - "aggregate3((address,bool,bytes)[])": { - "notice": "Aggregate calls, ensuring each returns success if required" - }, - "aggregate3Value((address,bool,uint256,bytes)[])": { - "notice": "Aggregate calls with a msg valueReverts if msg.value is less than the sum of the call values" - }, - "blockAndAggregate((address,bytes)[])": { - "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" - }, - "getBasefee()": { - "notice": "Gets the base fee of the given blockCan revert if the BASEFEE opcode is not implemented by the given chain" - }, - "getBlockHash(uint256)": { - "notice": "Returns the block hash for the given block number" - }, - "getBlockNumber()": { - "notice": "Returns the block number" - }, - "getChainId()": { - "notice": "Returns the chain id" - }, - "getCurrentBlockCoinbase()": { - "notice": "Returns the block coinbase" - }, - "getCurrentBlockDifficulty()": { - "notice": "Returns the block difficulty" - }, - "getCurrentBlockGasLimit()": { - "notice": "Returns the block gas limit" - }, - "getCurrentBlockTimestamp()": { - "notice": "Returns the block timestamp" - }, - "getEthBalance(address)": { - "notice": "Returns the (ETH) balance of a given address" - }, - "getLastBlockHash()": { - "notice": "Returns the block hash of the last block" - }, - "tryAggregate(bool,(address,bytes)[])": { - "notice": "Backwards-compatible with Multicall2Aggregate calls without requiring success" - }, - "tryBlockAndAggregate(bool,(address,bytes)[])": { - "notice": "Backwards-compatible with Multicall2Aggregate calls and allow failures using tryAggregate" - } - }, - "notice": "Aggregate results from multiple function calls", - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/contracts/hardhat/deployments/localhost/PreMining.json b/contracts/hardhat/deployments/localhost/PreMining.json deleted file mode 100644 index 9ba45a0b..00000000 --- a/contracts/hardhat/deployments/localhost/PreMining.json +++ /dev/null @@ -1,1039 +0,0 @@ -{ - "address": "0x9A676e781A523b5d0C0e43731313A708CB607508", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "lTokenAddress_", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxDistributedLDY_", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lockedHardCap_", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "minLockDuration_", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "maxLockDuration_", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "vestingDuration_", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint8", - "name": "duration", - "type": "uint8" - } - ], - "name": "Lock", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferStarted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "accountsLocks", - "outputs": [ - { - "internalType": "uint240", - "name": "amount", - "type": "uint240" - }, - { - "internalType": "uint8", - "name": "duration", - "type": "uint8" - }, - { - "internalType": "bool", - "name": "hasUnlocked", - "type": "bool" - }, - { - "internalType": "uint216", - "name": "claimedRewards", - "type": "uint216" - }, - { - "internalType": "uint40", - "name": "lockEndTimestamp", - "type": "uint40" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "availableToClaim", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "claimPhaseStartTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "claimRewards", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "eligibleRewardsOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "endDepositPhase", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "hasClaimPhaseStarted", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "hasDepositPhaseEnded", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "hasRecoveryPhaseStarted", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "instantUnlock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "lToken", - "outputs": [ - { - "internalType": "contract LToken", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ldyToken", - "outputs": [ - { - "internalType": "contract IERC20", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "duration", - "type": "uint8" - } - ], - "name": "lock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "lockedHardCap", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxDistributedLDY", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxLockDuration", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxWeight", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minLockDuration", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pendingOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "processUnlockRequests", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "recoverERC20", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "requestUnlock", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "ldyTokenAddress", - "type": "address" - } - ], - "name": "setLDYToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "startClaimPhase", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "startRecoveryPhase", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "totalLocked", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "underlyingToken", - "outputs": [ - { - "internalType": "contract IERC20", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "unlockRequests", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unlockRequestsCursor", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "vestingDuration", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "transactionHash": "0x730479e36a6fa3b8e9e563e0c2d3ba41fd3f8619bd354bb649ce0edc764a8986", - "receipt": { - "to": null, - "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "contractAddress": "0x9A676e781A523b5d0C0e43731313A708CB607508", - "transactionIndex": 0, - "gasUsed": "1907603", - "logsBloom": "0x00000000000080000000000000000000000000000000000000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000100000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000200000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc86fe8312831fb457a83de8df1aa296805cc2371d2bfde00e8f3c377639e900f", - "transactionHash": "0x730479e36a6fa3b8e9e563e0c2d3ba41fd3f8619bd354bb649ce0edc764a8986", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 15, - "transactionHash": "0x730479e36a6fa3b8e9e563e0c2d3ba41fd3f8619bd354bb649ce0edc764a8986", - "address": "0x9A676e781A523b5d0C0e43731313A708CB607508", - "topics": [ - "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" - ], - "data": "0x", - "logIndex": 0, - "blockHash": "0xc86fe8312831fb457a83de8df1aa296805cc2371d2bfde00e8f3c377639e900f" - } - ], - "blockNumber": 15, - "cumulativeGasUsed": "1907603", - "status": 1, - "byzantium": true - }, - "args": [ - "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", - "1125000000000000000000000", - "4000000000000", - 3, - 12, - 6 - ], - "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"lTokenAddress_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxDistributedLDY_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"lockedHardCap_\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"minLockDuration_\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"maxLockDuration_\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"vestingDuration_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"duration\",\"type\":\"uint8\"}],\"name\":\"Lock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accountsLocks\",\"outputs\":[{\"internalType\":\"uint240\",\"name\":\"amount\",\"type\":\"uint240\"},{\"internalType\":\"uint8\",\"name\":\"duration\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"hasUnlocked\",\"type\":\"bool\"},{\"internalType\":\"uint216\",\"name\":\"claimedRewards\",\"type\":\"uint216\"},{\"internalType\":\"uint40\",\"name\":\"lockEndTimestamp\",\"type\":\"uint40\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"availableToClaim\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimPhaseStartTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"eligibleRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"endDepositPhase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasClaimPhaseStarted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasDepositPhaseEnded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hasRecoveryPhaseStarted\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"instantUnlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lToken\",\"outputs\":[{\"internalType\":\"contract LToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ldyToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"duration\",\"type\":\"uint8\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedHardCap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDistributedLDY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLockDuration\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minLockDuration\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"processUnlockRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestUnlock\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ldyTokenAddress\",\"type\":\"address\"}],\"name\":\"setLDYToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startClaimPhase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startRecoveryPhase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalLocked\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"underlyingToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"unlockRequests\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockRequestsCursor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vestingDuration\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Lila Rest (https://lila.rest)\",\"custom:security-contact\":\"security@ledgity.comsecurity@ledgity.com\",\"details\":\"Intuition Lifecycle of a lockdrop pool is composed by 3 main phases: 1) Deposit: During this phase, users can lock their underlying tokens. 2) Claim: During this phase, users can claim their LDY rewards. 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract. Transitioning between two phases is manually triggered by contract's owner. To ensure fair usage of this power and prevent potential misuse: - the Recovery phase cannot start before 3 months after the end of rewards vesting, - the Recovery phase cannot start before 3 months after the maximum lock end. Finally, note that this contract proxies main L-Token contract's functions: - lock() --> deposit() - instantUnlock() --> instantWithdrawal() - requestUnlock() --> requestWithdrawal() This design enables users to interact with the PreMining contract in a similar fashion to the L-Token contract. Definitions: - Locker: An account that has locked underlying tokens in the pool. \",\"events\":{\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"}},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"availableToClaim(address)\":{\"details\":\"This function considers vesting and already claimed rewards.\",\"params\":{\"account\":\"The account to compute the available rewards of.\"},\"returns\":{\"_0\":\"The amount of LDY rewards available to claim.\"}},\"constructor\":{\"params\":{\"lTokenAddress_\":\"Address of the L-Token contract to use.\",\"lockedHardCap_\":\"Maximum total amount of L-Tokens that can be locked.\",\"maxDistributedLDY_\":\"Amount of LDY to be distributed to lockers.\",\"maxLockDuration_\":\"Maximum possible lock duration (in months).\",\"minLockDuration_\":\"Minimum possible lock duration (in months).\",\"vestingDuration_\":\"Duration of LDY rewards vesting (in months).\"}},\"eligibleRewardsOf(address)\":{\"details\":\"Note: This function neither considers vesting nor already claimed rewards.\",\"params\":{\"account\":\"The account to compute the eligible rewards of.\"},\"returns\":{\"_0\":\"The total amount of LDY rewards that the account is eligible to.\"}},\"instantUnlock()\":{\"details\":\"In order to save some gas and time to users, frontends should propose this function to users only when it has been verified that it will not revert. They should propose the requestUnlock() function otherwise.\"},\"lock(uint256,uint8)\":{\"details\":\"This function proxies LToken.deposit()Lockers can extend their lock duration by calling this function again with a greater duration and 0 as amount.\",\"params\":{\"amount\":\"Amount of underlying tokens to lock.\",\"duration\":\"Duration of the lock (in months).\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"recoverERC20(address,uint256)\":{\"params\":{\"amount\":\"The amount of token to recover.\",\"tokenAddress\":\"The address of the token to recover.\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"requestUnlock()\":{\"details\":\"The sender must attach 0.003 ETH to pre-pay the future processing gas fees paid by the withdrawer wallet.\"},\"setLDYToken(address)\":{\"details\":\"As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE, this function allows the contract's owner to set the LDY token address once it becomes available.\",\"params\":{\"ldyTokenAddress\":\"Address of the LDY token contract.\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"title\":\"PreMining\",\"version\":1},\"userdoc\":{\"events\":{\"Lock(address,uint256,uint8)\":{\"notice\":\"Emitted to inform about a new lock/deposit.\"}},\"kind\":\"user\",\"methods\":{\"accountsLocks(address)\":{\"notice\":\"Holds lockers' participations informations.\"},\"availableToClaim(address)\":{\"notice\":\"Computes the amount of LDY rewards available to claim for a given account.\"},\"claimPhaseStartTimestamp()\":{\"notice\":\"Holds the timestamp at which the Claim phase started.\"},\"claimRewards()\":{\"notice\":\"Allows the caller to claim its available LDY rewards.\"},\"constructor\":{\"notice\":\"This constructor function etches the lockdrop terms in immutable states. Ensuring that those terms cannot be modified after deployment.\"},\"eligibleRewardsOf(address)\":{\"notice\":\"Compute the total amount of LDY rewards that a given account is eligible to.\"},\"endDepositPhase()\":{\"notice\":\"Closes the Deposit phase. After calling this function, account won't be able to lock additional underlying tokens anymore.\"},\"hasClaimPhaseStarted()\":{\"notice\":\"Holds whether the Claim phase has started.\"},\"hasDepositPhaseEnded()\":{\"notice\":\"Holds whether the Deposit phase has ended.\"},\"hasRecoveryPhaseStarted()\":{\"notice\":\"Holds whether the Recovery phase has started.\"},\"instantUnlock()\":{\"notice\":\"Allows the caller to instaneously unlock its locked amount of underlying tokens.\"},\"lToken()\":{\"notice\":\"Holds a reference to the locked L-Token contract.\"},\"ldyToken()\":{\"notice\":\"Holds a reference to the LDY token contract.\"},\"lock(uint256,uint8)\":{\"notice\":\"Allows locking a specified amount of underlying tokens for a given duration. By locking, an account became eligible to a portion of the distributed LDY rewards.\"},\"lockedHardCap()\":{\"notice\":\"Holds the maximum total amount of L-Tokens that can be locked.\"},\"maxDistributedLDY()\":{\"notice\":\"Holds the amount of LDY to be distributed to lockers.\"},\"maxLockDuration()\":{\"notice\":\"Holds the maximum possible lock duration (in months).\"},\"maxWeight()\":{\"notice\":\"Holds the max pool weight.\"},\"minLockDuration()\":{\"notice\":\"Holds the minimum possible lock duration (in months).\"},\"pause()\":{\"notice\":\"Public implementation of Pausable's pausing and unpausing functions, but restricted to contract's owner.\"},\"processUnlockRequests()\":{\"notice\":\"Processes queued unlock requests until there is else no more requests, else not enough underlying tokens to continue.\"},\"recoverERC20(address,uint256)\":{\"notice\":\"Recovers a specified amount of a given token address. Will revert if recovery phase has not started yet or if the contract doesn't hold enough tokens.\"},\"requestUnlock()\":{\"notice\":\"Allows the call to request for the unlocking of its locked amount of underlying tokens. The request will be automatically processed later.\"},\"setLDYToken(address)\":{\"notice\":\"Updates the LDY token contract address.\"},\"startClaimPhase()\":{\"notice\":\"Opens the Claim phase. After calling this function, lockers will be able to start claiming their LDY rewards.\"},\"startRecoveryPhase()\":{\"notice\":\"Opens the Recovery phase. After calling this function, the contract owner will be able to recover remaining ERC20 tokens on the contract. Note that this won't close the Claim phase and lockers will still be able to claim their LDY rewards.\"},\"totalLocked()\":{\"notice\":\"Holds the total amount of locked underlying tokens.\"},\"underlyingToken()\":{\"notice\":\"Holds a reference to the L-Token underlying stablecoin.\"},\"unlockRequests(uint256)\":{\"notice\":\"Holds an ordered queue of accounts that requested to unlock their tokens.\"},\"unlockRequestsCursor()\":{\"notice\":\"Holds the index of the first request in the queue (a.k.a, next one to be processed).\"},\"vestingDuration()\":{\"notice\":\"Holds the duration of LDY rewards vesting (in months).\"}},\"notice\":\"PreMining pool contract, allowing accounts to lock underlying tokens in a pre-defined L-Token contract, over a given duration (in months), in exchange of vested LDY rewards. \",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/PreMining.sol\":\"PreMining\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n function __Ownable2Step_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable2Step_init_unchained() internal onlyInitializing {\\n }\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x84efb8889801b0ac817324aff6acc691d07bbee816b671817132911d287a8c63\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967Upgradeable {\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Emitted when the beacon is changed.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x47d6e06872b12e72c79d1b5eb55842f860b5fb1207b2317c2358d2766b950a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822ProxiableUpgradeable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x77c89f893e403efc6929ba842b7ccf6534d4ffe03afe31670b4a528c0ad78c0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeaconUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC1967Upgradeable.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/StorageSlotUpgradeable.sol\\\";\\nimport \\\"../utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\\n function __ERC1967Upgrade_init() internal onlyInitializing {\\n }\\n\\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\\n }\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(AddressUpgradeable.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(AddressUpgradeable.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x584ebdf9c1118a7c773f98788e3f3ede01982bdf8932aa06f5acc7d54876e161\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeaconUpgradeable {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0x24b86ac8c005b8c654fbf6ac34a5a4f61580d7273541e83e013e89d66fbf0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822Upgradeable.sol\\\";\\nimport \\\"../ERC1967/ERC1967UpgradeUpgradeable.sol\\\";\\nimport \\\"./Initializable.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\\n function __UUPSUpgradeable_init() internal onlyInitializing {\\n }\\n\\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\\n }\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeTo(address newImplementation) public virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n *\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb607cb94c27e89750f5ae2ccebcb94e654e926f6125f4fd4c6262c89875118ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0xd14a627157b9a411d2410713e5dd3a377e9064bd5c194a90748bbf27ea625784\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../security/PausableUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev ERC20 token with pausable token transfers, minting and burning.\\n *\\n * Useful for scenarios such as preventing trades until the end of an evaluation\\n * period, or having an emergency switch for freezing all token transfers in the\\n * event of a large bug.\\n *\\n * IMPORTANT: This contract does not include public pause and unpause functions. In\\n * addition to inheriting this contract, you must define both functions, invoking the\\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\\n * make the contract unpausable.\\n */\\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\\n function __ERC20Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {ERC20-_beforeTokenTransfer}.\\n *\\n * Requirements:\\n *\\n * - the contract must not be paused.\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\\n super._beforeTokenTransfer(from, to, amount);\\n\\n require(!paused(), \\\"ERC20Pausable: token transfer while paused\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xf0bd7f71ffae5f0addd375e8511fbf2ad8ca0c9b2606c32d92bdda7d76a7a81c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../utils/SafeERC20Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of the ERC20 token contract to support token wrapping.\\n *\\n * Users can deposit and withdraw \\\"underlying tokens\\\" and receive a matching number of \\\"wrapped tokens\\\". This is useful\\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\\n * wrapping of an existing \\\"basic\\\" ERC20 into a governance token.\\n *\\n * _Available since v4.2._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\\n IERC20Upgradeable private _underlying;\\n\\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n __ERC20Wrapper_init_unchained(underlyingToken);\\n }\\n\\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\\n require(underlyingToken != this, \\\"ERC20Wrapper: cannot self wrap\\\");\\n _underlying = underlyingToken;\\n }\\n\\n /**\\n * @dev See {ERC20-decimals}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\\n return value;\\n } catch {\\n return super.decimals();\\n }\\n }\\n\\n /**\\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\\n */\\n function underlying() public view returns (IERC20Upgradeable) {\\n return _underlying;\\n }\\n\\n /**\\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\\n */\\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\\n address sender = _msgSender();\\n require(sender != address(this), \\\"ERC20Wrapper: wrapper can't deposit\\\");\\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\\n _mint(account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\\n */\\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\\n _burn(_msgSender(), amount);\\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\\n * function that can be exposed with access control if desired.\\n */\\n function _recover(address account) internal virtual returns (uint256) {\\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\\n _mint(account, value);\\n return value;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x14bb62a60fcbc911c33ac0e5456bf31ed50b502c30be46ee15bd3b698e91bd81\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd60f939a3ca0199014d079b4dd66aa757954334947d81eb5c1d35d7a83061ab3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n using AddressUpgradeable for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20PermitUpgradeable token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0x23b997be73d3dd46885262704f0f8cfc7273fdadfe303d37969a9561373972b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlotUpgradeable {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n struct StringSlot {\\n string value;\\n }\\n\\n struct BytesSlot {\\n bytes value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n */\\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n */\\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n */\\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n */\\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := store.slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0x07ac95acad040f1fb1f6120dd0aa5f702db69446e95f82613721879d30de0908\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2Step is Ownable {\\n address private _pendingOwner;\\n\\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Returns the address of the pending owner.\\n */\\n function pendingOwner() public view virtual returns (address) {\\n return _pendingOwner;\\n }\\n\\n /**\\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual override onlyOwner {\\n _pendingOwner = newOwner;\\n emit OwnershipTransferStarted(owner(), newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual override {\\n delete _pendingOwner;\\n super._transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev The new owner accepts the ownership transfer.\\n */\\n function acceptOwnership() public virtual {\\n address sender = _msgSender();\\n require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n _transferOwnership(sender);\\n }\\n}\\n\",\"keccak256\":\"0xde231558366826d7cb61725af8147965a61c53b77a352cc8c9af38fc5a92ac3c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor() {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0x0849d93b16c9940beb286a7864ed02724b248b93e0d80ef6355af5ef15c64773\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Replacement to the LDYStaking contract until the $LDY token is available and\\n * the real LDYStaking can be deployed.\\n *\\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\\n * one the LToken contract relies on.\\n *\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LDYStaking is Ownable2Step {\\n /**\\n * @notice Holds a mapping of addresses that default to the highest staking tier.\\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\\n */\\n mapping(address => bool) public highTierAccounts;\\n\\n /**\\n * @notice Update high tier status of a given account.\\n * @param account The account to update the high tier status of.\\n */\\n function setHighTierAccount(address account, bool status) external onlyOwner {\\n highTierAccounts[account] = status;\\n }\\n\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * ellgible to any LDY staking tier, except if the account is in the\\n * defaultToHighestTier mapping.\\n * @param account The account to check the tier of.\\n */\\n function tierOf(address account) public view returns (uint256 tier) {\\n if (highTierAccounts[account]) return 3;\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x5d1fd1821e7d5d6cac7424373eb5cbfeebe6a075f897c7f62fb30241ea5b6309\",\"license\":\"MIT\"},\"contracts/src/GlobalBlacklist.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalBlacklist\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global mapping of blacklisted accounts on-chain. All contracts\\n * within the Ledgity Yield codebase reference this mapping to prevent access by\\n * blacklisted accounts.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\\n * and getter functions to easily check against this global blacklist.\\n *\\n * @dev For further details, see \\\"GlobalBlacklist\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\\n /**\\n * @notice Mapping of accounts to their blacklist status.\\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\\n */\\n mapping(address => bool) private _list;\\n\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @notice Adds a given account to the blacklist.\\n * @param account The account's address to be blacklisted.\\n */\\n function blacklist(address account) external onlyOwner {\\n require(account != address(0), \\\"L20\\\");\\n _list[account] = true;\\n }\\n\\n /**\\n * @notice Removes a given account from the blacklist.\\n * @param account The account's address to be un-blacklisted.\\n */\\n function unBlacklist(address account) external onlyOwner {\\n _list[account] = false;\\n }\\n\\n /**\\n * @notice Checks whether a given account is blacklisted.\\n * @param account Address of the account to check.\\n * @return 'true' if the account is blacklisted, 'false' otherwise\\n */\\n function isBlacklisted(address account) external view returns (bool) {\\n // Gas optimization: Avoid accessing storage if account is the zero address\\n // (e.g, during a mint or a burn of tokens)\\n if (account == address(0)) return false;\\n\\n // Else, return current account's blacklist status\\n return _list[account];\\n }\\n}\\n\",\"keccak256\":\"0x8e4d4072f74f9d683bf0b54d76fa08201cf507eb791d217178a0ee9d6aaa3ddf\",\"license\":\"MIT\"},\"contracts/src/GlobalOwner.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {Ownable2StepUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalOwner\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains the address of a global owner account shared by all contracts of the\\n * Ledgity Yield's codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\\n * owner() function that retrieves the owner's address from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalOwner\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n */\\n function initialize() public initializer {\\n __Ownable2Step_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n}\\n\",\"keccak256\":\"0xe539a2010c0dfb59a9084d9ee1a7e1b92228b9e8557df50d477eee653657e987\",\"license\":\"MIT\"},\"contracts/src/GlobalPause.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./abstracts/GlobalOwnableUpgradeable.sol\\\";\\n\\n/**\\n * @title GlobalPause\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Maintains a global pause state shared by all contracts of the Ledgity Yield\\n * codebase.\\n *\\n * @dev Specifically, some contracts within the codebase inherit from the\\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\\n * paused() function that retrieves the pause state from this contract instead.\\n *\\n * @dev For further details, see \\\"GlobalPause\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract GlobalPause is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n PausableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function initialize(address globalOwner_) public initializer {\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __UUPSUpgradeable_init();\\n }\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\\n * but restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n}\\n\",\"keccak256\":\"0x5933aec9779d2d84e00678bf489c8349d8be84fcf479f2a18eb8571a3b900ada\",\"license\":\"MIT\"},\"contracts/src/LToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Contracts\\nimport {ERC20WrapperUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\\\";\\nimport \\\"./abstracts/base/ERC20BaseUpgradeable.sol\\\";\\nimport {InvestUpgradeable} from \\\"./abstracts/InvestUpgradeable.sol\\\";\\nimport {LDYStaking} from \\\"./DummyLDYStaking.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {SUD} from \\\"./libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport {ITransfersListener} from \\\"./interfaces/ITransfersListener.sol\\\";\\n\\n/**\\n * @title LToken\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e,\\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\\n * the form of additional L-Tokens, which are auto-compounded over time.\\n *\\n * @dev Definitions:\\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\\n * - Instant: Processed immediately.\\n * - Requested: Queued for later processing.\\n * - Big Requested: A requested withdrawal exceeding half of the retention rate.\\n * - (Withdrawal) queue: An list of all requested withdrawals sorted by priority.\\n * - Request ID: The index of a withdrawal request in the queue array.\\n * - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain.\\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\\n * expected ways and are so considered as safe to use by the contract.\\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\\n * processing.\\n *\\n * Note that words between parenthesis are sometimes omitted for brevity.\\n *\\n * @dev Security: This contract can safely receive funds immediately after initialization.\\n * (i.e., there is no way for funds to be sent to non-owned addresses). It is however\\n * recommended to replace ASAP owner and fund wallets by multi-sig wallets.\\n *\\n * @dev For further details, see \\\"LToken\\\" section of whitepaper.\\n * @custom:oz-upgrades-unsafe-allow external-library-linking\\n * @custom:security-contact security@ledgity.com\\n */\\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /// @dev Represents type of actions triggering ActivityEvent events.\\n enum Action {\\n Deposit,\\n Withdraw\\n }\\n\\n /// @dev Represents different status of actions triggering ActivityEvent events.\\n enum Status {\\n Queued,\\n Cancelled,\\n Success,\\n Moved\\n }\\n\\n /**\\n * @notice Represents a withdrawal request in the queue.\\n * @dev A request fits in a single storage slot (32 bytes).\\n * @param account The account that initiated the request.\\n * @param amount The amount of underlying tokens requested.\\n */\\n struct WithdrawalRequest {\\n address account; // 20 bytes\\n uint96 amount; // 12 bytes\\n }\\n\\n /// @notice Upper limit of retention rate.\\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\\n\\n /// @notice Used in activity events to represent the absence of request ID.\\n int256 private constant NO_ID = -1;\\n\\n /// @notice Holds a reference to the LDYStaking contract.\\n LDYStaking public ldyStaking;\\n\\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\\n address payable public withdrawer;\\n\\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\\n address public fund;\\n\\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\\n uint32 public feesRateUD7x3;\\n\\n /// @notice Holds the retention rate in UD7x3 format.\\n uint32 public retentionRateUD7x3;\\n\\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\\n uint256 public unclaimedFees;\\n\\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\\n uint256 public totalQueued;\\n\\n /**\\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\\n */\\n uint256 public usableUnderlyings;\\n\\n /// @notice Holds an ordered list of active withdrawal requests.\\n WithdrawalRequest[] public withdrawalQueue;\\n\\n /// @notice Holds the index of the next withdrawal request to process in the queue.\\n uint256 public withdrawalQueueCursor;\\n\\n /**\\n * @notice Holds a list of all currently frozen withdrawal requests.\\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\\n * it from blocking the queue.\\n */\\n WithdrawalRequest[] public frozenRequests;\\n\\n /**\\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\\n */\\n ITransfersListener[] public transfersListeners;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the contract's TVL.\\n * @dev TVL = realTotalSupply()\\n * @param newTVL The new TVL of the contract.\\n */\\n event TVLChangeEvent(uint256 newTVL);\\n\\n /**\\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\\n * @param account The account involved in the activity.\\n * @param action The type of activity.\\n * @param amount The amount of underlying tokens involved in the activity.\\n * @param newStatus The new status of the activity.\\n * @param newId The new ID of the request if it has been moved in the queue.\\n */\\n event ActivityEvent(\\n int256 indexed id,\\n address indexed account,\\n Action indexed action,\\n uint256 amount,\\n uint256 amountAfterFees,\\n Status newStatus,\\n int256 newId\\n );\\n\\n /**\\n * @notice Emitted to inform listeners that some rewards have been minted.\\n * @param account The account that received the rewards.\\n * @param balanceBefore The balance of the account before the minting.\\n * @param rewards The amount of minted rewards.\\n */\\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\\n\\n /// @notice Reverts if the function caller is not the withdrawer wallet.\\n modifier onlyWithdrawer() {\\n require(_msgSender() == withdrawer, \\\"L39\\\");\\n _;\\n }\\n\\n /// @notice Reverts if the function caller is not the fund wallet.\\n modifier onlyFund() {\\n require(_msgSender() == fund, \\\"L40\\\");\\n _;\\n }\\n\\n /**\\n * @notice Initializer function of the contract. It replaces the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\\n */\\n function initialize(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address ldyStaking_,\\n address underlyingToken\\n ) public initializer {\\n // Initialize ERC20 base.\\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\\n __ERC20Base_init(\\n globalOwner_,\\n globalPause_,\\n globalBlacklist_,\\n string(abi.encodePacked(\\\"Ledgity \\\", underlyingSymbol)),\\n string(abi.encodePacked(\\\"L\\\", underlyingSymbol))\\n );\\n\\n // IMPORTANT: Below calls must not be restricted to owner at any point.\\n // This is because the GlobalOwner contract may not be a fresh one, and so\\n // the contract deployer may not be the owner anymore after ERC20Base init.\\n\\n // Initialize other parents contracts.\\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\\n __Invest_init_unchained(address(this));\\n\\n // Set LDYStaking contract\\n ldyStaking = LDYStaking(ldyStaking_);\\n\\n // Set initial withdrawal fees rate to 0.3%\\n feesRateUD7x3 = 300;\\n\\n // Set initial retention rate to 10%\\n retentionRateUD7x3 = 10_000;\\n\\n // Default withdrawer and fund wallet to contract owner address. This prevents\\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\\n withdrawer = payable(owner());\\n fund = payable(owner());\\n }\\n\\n /**\\n * @notice Required override of decimals() which is implemented by both\\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\\n * decimals amount of the underlying stablecoin token.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function decimals()\\n public\\n view\\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\\n returns (uint8)\\n {\\n return ERC20WrapperUpgradeable.decimals();\\n }\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @notice Updates the current withdrawal fee rate.\\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\\n */\\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\\n feesRateUD7x3 = feesRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the current underlying token retention rate.\\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\\n * deposited assets will ever be exposed in this contract (reduces attack surface).\\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\\n */\\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \\\"L41\\\");\\n retentionRateUD7x3 = retentionRateUD7x3_;\\n }\\n\\n /**\\n * @notice Updates the address of LDYStaking contract.\\n * @param ldyStakingAddress The address of the new LDYStaking contract.\\n */\\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\\n ldyStaking = LDYStaking(ldyStakingAddress);\\n }\\n\\n /**\\n * @notice Updates the address of the withdrawer wallet.\\n * @param withdrawer_ The address of the new withdrawer wallet.\\n */\\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\\n // Ensure address is not the zero address (pre-processing fees would be lost else)\\n require(withdrawer_ != address(0), \\\"L63\\\");\\n\\n // Set new withdrawer wallet's address\\n withdrawer = withdrawer_;\\n }\\n\\n /**\\n * @notice Updates the address of the fund wallet.\\n * @param fund_ The address of the new fund wallet.\\n */\\n function setFund(address payable fund_) public onlyOwner {\\n // Ensure address is not the zero address (deposited tokens would be lost else)\\n require(fund_ != address(0), \\\"L64\\\");\\n\\n // Set new fund wallet's address\\n fund = fund_;\\n }\\n\\n /**\\n * @notice Adds a new contract to the L-Token transfers list.\\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\\n * specified contract will be called.\\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\\n * contracts that are not owned by the Ledgity team.\\n * @param listenerContract The address of the new transfers listener contract.\\n */\\n function listenToTransfers(address listenerContract) public onlyOwner {\\n transfersListeners.push(ITransfersListener(listenerContract));\\n }\\n\\n /**\\n * @notice Removes a contract from the L-Token transfers list.\\n * @dev The onLTokenTransfer() function of the specified contract will not be called\\n * anymore each time a L-Token transfer occurs.\\n * @param listenerContract The address of the listener contract.\\n */\\n function unlistenToTransfers(address listenerContract) public onlyOwner {\\n // Find index of listener contract in transferListeners array\\n int256 index = -1;\\n uint256 transfersListenersLength = transfersListeners.length;\\n for (uint256 i = 0; i < transfersListenersLength; i++) {\\n if (address(transfersListeners[i]) == listenerContract) {\\n index = int256(i);\\n break;\\n }\\n }\\n\\n // Revert if given contract wasn't listening to transfers\\n require(index > -1, \\\"L42\\\");\\n\\n // Else, remove transfers listener contract from listeners array\\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\\n transfersListeners.pop();\\n }\\n\\n /**\\n * @notice Retrieves the amount of given account's not yet minted rewards.\\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\\n * context of LToken, this function returns the amount of rewards that have not been\\n * distributed/minted yet to the specified account.\\n * @dev This is particularly useful for off-chain services to display charts and\\n * statistics, as seen in the Ledgity Yield's frontend.\\n * @param account The account to check the unminted rewards of.\\n * @return The amount of account's unminted rewards.\\n */\\n function unmintedRewardsOf(address account) public view returns (uint256) {\\n return _rewardsOf(account, true);\\n }\\n\\n /**\\n * @notice Retrieves the \\\"real\\\" balance of an account, i.e., excluding its not yet\\n * minted/distributed rewards.\\n * @param account The account to check the real balance of.\\n * @return The real balance of the account.\\n */\\n function realBalanceOf(address account) public view returns (uint256) {\\n return super.balanceOf(account);\\n }\\n\\n /**\\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\\n * not been yet minted to the specified account.\\n * @param account The account to check the total balance of.\\n * @return The total balance of the account.\\n */\\n function balanceOf(address account) public view override returns (uint256) {\\n return realBalanceOf(account) + unmintedRewardsOf(account);\\n }\\n\\n /**\\n * @notice Returns the \\\"real\\\" amount of existing L-Tokens, i.e., excluding not yet\\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\\n * @return The real total supply of L-Tokens.\\n */\\n function realTotalSupply() public view returns (uint256) {\\n return super.totalSupply();\\n }\\n\\n /**\\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\\n * fees and L-Tokens currently in the withdrawal queue.\\n * @return The total supply of L-Tokens.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return realTotalSupply() + totalQueued + unclaimedFees;\\n }\\n\\n /**\\n * @notice Recovers a specified amount of a given token address.\\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\\n * token from being the underlying token.\\n * @inheritdoc RecoverableUpgradeable\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\\n // Ensure the token is not the underlying token\\n require(tokenAddress != address(underlying()), \\\"L43\\\");\\n\\n // Proceed to recovery\\n super.recoverERC20(tokenAddress, amount);\\n }\\n\\n /**\\n * @notice Recovers underlying tokens accidentally sent to the contract.\\n * @dev To prevent owner from being able to drain the contract, this function only\\n * allows recovering \\\"unusable\\\" underlying tokens, i.e., tokens that have not been\\n * sent through fund() or deposit() functions.\\n */\\n function recoverUnderlying() external onlyOwner {\\n // Compute the recoverable amount by taking the difference between the contract's\\n // balance and the amount of usable underlying tokens\\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\\n\\n // Revert if there is nothing to recover\\n require(recoverableAmount > 0, \\\"L44\\\");\\n\\n // Else, proceed to underlying tokens recovery\\n super.recoverERC20(address(underlying()), recoverableAmount);\\n }\\n\\n /**\\n * @notice Retrieves the amount of underlying tokens invested by the given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\\n * LToken contract, the investment of an account is equal to its real balance.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _investmentOf(address account) internal view override returns (uint256) {\\n return realBalanceOf(account);\\n }\\n\\n /**\\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\\n * @dev Implementing this function is required by the InvestUpgradeable contract so\\n * it can distribute rewards to accounts before each period reset.\\n * @dev InvestUpgradeable contract already ensure that amount > 0.\\n * @inheritdoc InvestUpgradeable\\n */\\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\\n // Inform listeners of the rewards minting\\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\\n\\n // Mint L-Tokens rewards to account\\n _mint(account, amount);\\n\\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\\n return true;\\n }\\n\\n /**\\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\\n * called each time an account's balance is going to change.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\\n * @inheritdoc ERC20BaseUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\\n\\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\\n if (from != address(0)) _beforeInvestmentChange(from, true);\\n if (to != address(0)) _beforeInvestmentChange(to, true);\\n }\\n\\n /**\\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\\n * transfers listeners.\\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\\n * already checked in _beforeTokenTransfer().\\n * @inheritdoc ERC20Upgradeable\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n // If some L-Token have been burned/minted, inform listeners of a TVL change\\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\\n\\n // Trigger onLTokenTransfer() functions of all the transfers listeners\\n for (uint256 i = 0; i < transfersListeners.length; i++) {\\n transfersListeners[i].onLTokenTransfer(from, to, amount);\\n }\\n }\\n\\n /**\\n * @notice Computes the maximum amount of underlying tokens that should be retained\\n * by the contract (based on retention rate).\\n * @return amount The expected amount of retained underlying tokens.\\n */\\n function getExpectedRetained() public view returns (uint256 amount) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert totalSupply and retentionRate to SUD\\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\\n\\n // Compute and return expected retained amount\\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(expectedRetainedSUD, d);\\n }\\n\\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\\n function _transferExceedingToFund() internal {\\n // Retrieve the expected amount retained\\n uint256 expectedRetained = getExpectedRetained();\\n\\n // If usable underlyings are less than or equal to expected retained, return\\n if (usableUnderlyings <= expectedRetained) return;\\n\\n // Else, exceeding amount is equal to difference between those values\\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= exceedingAmount;\\n\\n // Transfer the exceeding amount to the fund wallet\\n underlying().safeTransfer(fund, exceedingAmount);\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L45\\\");\\n }\\n\\n /**\\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\\n * Use deposit() function instead.\\n * @inheritdoc ERC20WrapperUpgradeable\\n */\\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\\n account; // Silence unused variable compiler warning\\n amount;\\n revert(\\\"L46\\\");\\n }\\n\\n /**\\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\\n * @param amount The amount of underlying tokens to deposit.\\n */\\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough underlying tokens to deposit\\n require(underlying().balanceOf(_msgSender()) >= amount, \\\"L47\\\");\\n\\n // Update usable underlyings balance accordingly\\n usableUnderlyings += amount;\\n\\n // Inform listeners of the deposit activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Deposit,\\n amount,\\n amount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\\n super.depositFor(_msgSender(), amount);\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\\n * given amount.\\n * @param account The account initiating the withdrawal.\\n * @param amount The amount of the withdrawal.\\n */\\n function getWithdrawnAmountAndFees(\\n address account,\\n uint256 amount\\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\\n // If the account is eligible to staking tier 2, no fees are applied\\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\\n\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Convert amount and fees rate to SUD\\n uint256 amountSUD = SUD.fromAmount(amount, d);\\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\\n\\n // Compute fees and withdrawn amount (initial amount minus fees)\\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\\n fees = SUD.toAmount(feesSUD, d);\\n withdrawnAmount = amount - fees;\\n }\\n\\n /**\\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\\n * enough underlying tokens to cover the withdrawal.\\n * @dev In order to save some gas and time to users, frontends should propose this\\n * function to users only when it has been verified that it will not revert. They\\n * should propose the requestWithdrawal() function otherwise.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L48\\\");\\n\\n // Can the contract cover this withdrawal plus all already queued requests?\\n bool cond1 = totalQueued + amount <= usableUnderlyings;\\n\\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\\n\\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\\n if (!(cond1 || cond2)) revert(\\\"L49\\\");\\n\\n // Else, retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\\n\\n // Increase unclaimed fees amount accordingly\\n unclaimedFees += fees;\\n\\n // Decrease usable underlyings balance accordingly\\n usableUnderlyings -= withdrawnAmount;\\n\\n // Inform listeners of this instant withdrawal activity event\\n emit ActivityEvent(\\n NO_ID,\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Burn withdrawal fees from the account\\n _burn(_msgSender(), fees);\\n\\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\\n super.withdrawTo(_msgSender(), withdrawnAmount);\\n }\\n\\n /**\\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\\n * amount of underlying tokens. The request will be automatically processed later.\\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\\n * paid by the withdrawer wallet.\\n * @param amount The amount L-Tokens to withdraw.\\n */\\n function requestWithdrawal(\\n uint256 amount\\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\\n // Ensure the account has enough L-Tokens to withdraw\\n require(amount <= balanceOf(_msgSender()), \\\"L53\\\");\\n\\n // Ensure the requested amount doesn't overflow uint96\\n require(amount <= type(uint96).max, \\\"L54\\\");\\n\\n // Ensure the sender attached the pre-paid processing gas fees\\n require(msg.value == 0.003 * 10 ** 18, \\\"L55\\\");\\n\\n // Create withdrawal request data\\n WithdrawalRequest memory request = WithdrawalRequest({\\n account: _msgSender(),\\n amount: uint96(amount)\\n });\\n\\n // Will hold the request ID\\n uint256 requestId;\\n\\n // Append request to the withdrawal queue:\\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\\n withdrawalQueueCursor--;\\n requestId = withdrawalQueueCursor;\\n withdrawalQueue[requestId] = request;\\n }\\n // - At the end else\\n else {\\n withdrawalQueue.push(request);\\n requestId = withdrawalQueue.length - 1;\\n }\\n\\n // Increase total amount queued accordingly\\n totalQueued += amount;\\n\\n // Inform listeners of this new queued withdrawal activity event\\n emit ActivityEvent(\\n int256(requestId),\\n _msgSender(),\\n Action.Withdraw,\\n amount,\\n amount,\\n Status.Queued,\\n NO_ID\\n );\\n\\n // Burn withdrawal L-Tokens amount from account's balance\\n _burn(_msgSender(), amount);\\n\\n // Forward pre-paid processing gas fees to the withdrawer wallet\\n (bool sent, ) = withdrawer.call{value: msg.value}(\\\"\\\");\\n require(sent, \\\"L56\\\");\\n }\\n\\n /**\\n * @notice Processes queued withdrawal requests until there is else no more requests,\\n * else not enough underlying tokens to continue.\\n * @dev For further details, see \\\"LToken > Withdrawals\\\" section of whitepaper.\\n */\\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\\n // Accumulators variables, will be written on-chain after the loop\\n uint256 cumulatedFees = 0;\\n uint256 cumulatedWithdrawnAmount = 0;\\n uint256 nextRequestId = withdrawalQueueCursor;\\n\\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\\n // requests are increasing the queue length when moved at the end of the queue.\\n uint256 queueLength = withdrawalQueue.length;\\n\\n // Iterate over requests to be processed\\n while (nextRequestId < queueLength) {\\n // Stop processing requests if there is not enough gas left to continue the\\n // loop and properly end the function call. This prevents an attacker from\\n // blocking the withdrawal processing by creating a ton of tiny requests so\\n // this function call cannot fit anymore in block gas limit.\\n if (gasleft() < 45000) break;\\n\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\\n\\n // Skip empty request (processed big requests or cancelled requests)\\n if (request.account == address(0)) {}\\n //\\n // If account has been blacklisted since request emission\\n else if (isBlacklisted(request.account)) {\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request in the frozen requests list\\n frozenRequests.push(request);\\n }\\n //\\n // Or if request is a big request, move it at the end of the queue for now.\\n // This request will be processed manually later using processBigQueuedRequest()\\n else if (request.amount > getExpectedRetained() / 2) {\\n // Inform listeners of this queued request being moved at the end of the queue\\n emit ActivityEvent(\\n int256(nextRequestId),\\n _msgSender(),\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Moved,\\n int256(withdrawalQueue.length)\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Append request at the end of the queue\\n withdrawalQueue.push(request);\\n }\\n //\\n // Else, continue request processing\\n else {\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Break if the contract doesn't hold enough funds to cover the request\\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\\n\\n // Accumulate fees and withdrawn amount\\n cumulatedFees += fees;\\n cumulatedWithdrawnAmount += withdrawnAmount;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(nextRequestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[nextRequestId];\\n\\n // Transfer underlying tokens to account. Burning L-Tokens is not required\\n // as equestWithdrawal() already did it.\\n // Security note: Re-entrancy warning are disabled as the request has\\n // just been deleted from the queue, it will so be skipped if trying to\\n // process it again.\\n // slither-disable-next-line reentrancy-no-eth\\n underlying().safeTransfer(request.account, withdrawnAmount);\\n }\\n\\n // Increment next request ID\\n nextRequestId++;\\n }\\n\\n // Increase unclaimed fees by the amount of cumulated fees\\n unclaimedFees += cumulatedFees;\\n\\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\\n usableUnderlyings -= cumulatedWithdrawnAmount;\\n\\n // Decrease total amount queued by the cumulated amount requested\\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\\n\\n // Update new queue cursor\\n withdrawalQueueCursor = nextRequestId;\\n\\n // Retention rate cannot exceeds as the withdrawal decreases both usable\\n // underlyings and expected retained amounts by the same number and as the\\n // expected retained amount is a subset of usable underlyings amount.\\n }\\n\\n /**\\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\\n * the retention rate).\\n * @dev In contrast to non-big requests processing, this function will uses to fund\\n * wallet's balance to fill the request. This allows processing requests that are\\n * greater than retention rate without having to exceed this rate on the contract.\\n * @param requestId The ID of the big request to process.\\n */\\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure the request is active\\n require(request.account != address(0), \\\"L66\\\");\\n\\n // Ensure the request emitter has not been blacklisted since request emission\\n require(!isBlacklisted(request.account), \\\"L50\\\");\\n\\n // Ensure this is indeed a big request\\n require(request.amount > getExpectedRetained() / 2, \\\"L51\\\");\\n\\n // Retrieve withdrawal fees and net withdrawn amount\\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\\n request.account,\\n request.amount\\n );\\n\\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\\n uint256 fundBalance = underlying().balanceOf(fund);\\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \\\"L52\\\");\\n\\n // Increase amount of unclaimed fees accordingly\\n unclaimedFees += fees;\\n\\n // Decrease total queued amount by request amount\\n totalQueued -= request.amount;\\n\\n // Increment queue cursor if request was the next request to be processed\\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\\n\\n // Inform listeners of this queued withdrawal processing activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n withdrawnAmount,\\n Status.Success,\\n NO_ID\\n );\\n\\n // Remove request from queue\\n delete withdrawalQueue[requestId];\\n\\n // If fund wallet's balance can cover request, rely on it only\\n if (withdrawnAmount <= fundBalance) {\\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\\n }\\n // Else, cover request from both fund wallet and contract balances\\n else {\\n // Compute amount missing from fund wallet to cover request\\n uint256 missingAmount = withdrawnAmount - fundBalance;\\n\\n // Decrease usable amount of underlying tokens accordingly\\n usableUnderlyings -= missingAmount;\\n\\n // Transfer entire fund balance to request's emitter\\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\\n\\n // Transfer missing amount from contract balance to request emitter\\n underlying().safeTransfer(request.account, missingAmount);\\n }\\n\\n // Transfer exceeding underlying tokens to the fund wallet\\n _transferExceedingToFund();\\n }\\n\\n /**\\n * @notice Cancels a given withdrawal request. The request emitter receive back its\\n * L-Tokens and no fees will be charged.\\n * @param requestId The ID of the withdrawal request to cancel.\\n */\\n function cancelWithdrawalRequest(\\n uint256 requestId\\n ) public whenNotPaused notBlacklisted(_msgSender()) {\\n // Retrieve request data\\n WithdrawalRequest memory request = withdrawalQueue[requestId];\\n\\n // Ensure request belongs to caller\\n require(_msgSender() == request.account, \\\"L57\\\");\\n\\n // Decrease total amount queued accordingly\\n totalQueued -= request.amount;\\n\\n // Delete the withdrawal request from queue\\n delete withdrawalQueue[requestId];\\n\\n // Inform listeners of this cancelled withdrawal request activity event\\n emit ActivityEvent(\\n int256(requestId),\\n request.account,\\n Action.Withdraw,\\n request.amount,\\n request.amount,\\n Status.Cancelled,\\n NO_ID\\n );\\n\\n // Mint back L-Tokens to account\\n _mint(request.account, uint256(request.amount));\\n }\\n\\n /**\\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\\n * whenever those are required to fulfill some withdrawal requests.\\n * @dev The function will revert if repatriated amount makes the contract exceeding\\n * the retention rate.\\n * @param amount The amount of underlying tokens to repatriate.\\n */\\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\\n // Ensure the fund wallet has enough funds to repatriate\\n require(amount <= underlying().balanceOf(fund), \\\"L58\\\");\\n\\n // Calculate new contract usable balance\\n uint256 newBalance = usableUnderlyings + amount;\\n\\n // Ensure the new balance doesn't exceed the retention rate\\n require(newBalance <= getExpectedRetained(), \\\"L59\\\");\\n\\n // Increase usable underlyings amount by repatriated amount\\n usableUnderlyings += amount;\\n\\n // Transfer amount from fund wallet to contract\\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\\n }\\n\\n /// @notice Used by owner to claim fees generated from successful withdrawals.\\n function claimFees() external onlyOwner {\\n // Ensure there are some fees to claim\\n require(unclaimedFees > 0, \\\"L60\\\");\\n\\n // Ensure the contract holds enough underlying tokens to cover fees\\n require(usableUnderlyings >= unclaimedFees, \\\"L61\\\");\\n\\n // Decrease usable underlyings amount accordingly\\n usableUnderlyings -= unclaimedFees;\\n\\n // Store fees amount in memory and reset unclaimed fees amount\\n uint256 fees = unclaimedFees;\\n unclaimedFees = 0;\\n\\n // Transfer unclaimed fees to owner\\n underlying().safeTransfer(owner(), fees);\\n }\\n}\\n\",\"keccak256\":\"0x03fb59d6d4523deb913cf263137bb0f6d71c5a790aa2ec3556607fcf53184c8e\",\"license\":\"MIT\"},\"contracts/src/PreMining.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {LToken} from \\\"./LToken.sol\\\";\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable2Step} from \\\"@openzeppelin/contracts/access/Ownable2Step.sol\\\";\\nimport {Pausable} from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\n\\n/**\\n * @title PreMining\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n\\n * @notice PreMining pool contract, allowing accounts to lock underlying tokens in a \\n * pre-defined L-Token contract, over a given duration (in months), in exchange of \\n * vested LDY rewards.\\n * \\n * @dev Intuition\\n * \\n * Lifecycle of a lockdrop pool is composed by 3 main phases:\\n * 1) Deposit: During this phase, users can lock their underlying tokens.\\n * 2) Claim: During this phase, users can claim their LDY rewards.\\n * 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract.\\n * \\n * Transitioning between two phases is manually triggered by contract's owner.\\n * To ensure fair usage of this power and prevent potential misuse:\\n * - the Recovery phase cannot start before 3 months after the end of rewards vesting,\\n * - the Recovery phase cannot start before 3 months after the maximum lock end.\\n * \\n * Finally, note that this contract proxies main L-Token contract's functions:\\n * - lock() --> deposit()\\n * - instantUnlock() --> instantWithdrawal()\\n * - requestUnlock() --> requestWithdrawal()\\n * This design enables users to interact with the PreMining contract in a similar fashion\\n * to the L-Token contract.\\n * \\n * @dev Definitions:\\n * - Locker: An account that has locked underlying tokens in the pool.\\n * \\n * @custom:security-contact security@ledgity.com\\n */\\ncontract PreMining is Ownable2Step, Pausable {\\n using SafeERC20 for IERC20;\\n\\n /**\\n * @notice Represents the lock information of an account.\\n * @param amount Amount of underlying tokens locked.\\n * @param duration Duration of the lock (in months).\\n * @param hasUnlocked Whether the account has unlocked its locked tokens.\\n * @param claimedRewards Amount of LDY rewards already claimed.\\n * @param lockEndTimestamp Timestamp at which the account's lock ends.\\n */\\n struct AccountLock {\\n uint240 amount;\\n uint8 duration;\\n bool hasUnlocked;\\n uint216 claimedRewards;\\n uint40 lockEndTimestamp;\\n }\\n\\n /// @notice Holds the amount of LDY to be distributed to lockers.\\n uint256 public immutable maxDistributedLDY;\\n\\n /// @notice Holds the maximum total amount of L-Tokens that can be locked.\\n uint256 public immutable lockedHardCap;\\n\\n /// @notice Holds the minimum possible lock duration (in months).\\n uint8 public immutable minLockDuration;\\n\\n /// @notice Holds the maximum possible lock duration (in months).\\n uint8 public immutable maxLockDuration;\\n\\n /// @notice Holds the duration of LDY rewards vesting (in months).\\n uint8 public immutable vestingDuration;\\n\\n /// @notice Holds a reference to the locked L-Token contract.\\n LToken public immutable lToken;\\n\\n /// @notice Holds a reference to the L-Token underlying stablecoin.\\n IERC20 public immutable underlyingToken;\\n\\n /// @notice Holds the max pool weight.\\n uint256 public immutable maxWeight;\\n\\n /// @notice Holds a reference to the LDY token contract.\\n IERC20 public ldyToken;\\n\\n /// @notice Holds lockers' participations informations.\\n mapping(address => AccountLock) public accountsLocks;\\n\\n /// @notice Holds the total amount of locked underlying tokens.\\n uint256 public totalLocked;\\n\\n /// @notice Holds whether the Deposit phase has ended.\\n bool public hasDepositPhaseEnded;\\n\\n /// @notice Holds whether the Claim phase has started.\\n bool public hasClaimPhaseStarted;\\n\\n /// @notice Holds whether the Recovery phase has started.\\n bool public hasRecoveryPhaseStarted;\\n\\n /// @notice Holds the timestamp at which the Claim phase started.\\n uint256 public claimPhaseStartTimestamp;\\n\\n /// @notice Holds an ordered queue of accounts that requested to unlock their tokens.\\n address[] public unlockRequests;\\n\\n /// @notice Holds the index of the first request in the queue (a.k.a, next one to be processed).\\n uint256 public unlockRequestsCursor;\\n\\n /// @notice Emitted to inform about a new lock/deposit.\\n event Lock(address indexed account, uint256 amount, uint8 duration);\\n\\n /// @notice Top-level checks and code shared by both unlock functions.\\n modifier safeUnlock() {\\n // Ensure that the account's lock has ended\\n require(accountsLocks[msg.sender].lockEndTimestamp <= block.timestamp, \\\"L68\\\");\\n\\n // Ensure the account hasn't already unlocked its tokens\\n require(!accountsLocks[msg.sender].hasUnlocked, \\\"L69\\\");\\n\\n // Ensure the account has something to unlock\\n require(accountsLocks[msg.sender].amount > 0, \\\"L70\\\");\\n\\n // Indicate that account has unlocked its tokens\\n accountsLocks[msg.sender].hasUnlocked = true;\\n _;\\n }\\n\\n /**\\n * @notice This constructor function etches the lockdrop terms in immutable states.\\n * Ensuring that those terms cannot be modified after deployment.\\n * @param lTokenAddress_ Address of the L-Token contract to use.\\n * @param maxDistributedLDY_ Amount of LDY to be distributed to lockers.\\n * @param lockedHardCap_ Maximum total amount of L-Tokens that can be locked.\\n * @param minLockDuration_ Minimum possible lock duration (in months).\\n * @param maxLockDuration_ Maximum possible lock duration (in months).\\n * @param vestingDuration_ Duration of LDY rewards vesting (in months).\\n */\\n constructor(\\n address lTokenAddress_,\\n uint256 maxDistributedLDY_,\\n uint256 lockedHardCap_,\\n uint8 minLockDuration_,\\n uint8 maxLockDuration_,\\n uint8 vestingDuration_\\n ) {\\n // Ensure minLockDuration is at least 1 month\\n require(minLockDuration_ >= 1, \\\"L72\\\");\\n\\n // Ensure minLockDuration is not greater than maxLockDuration\\n require(minLockDuration_ <= maxLockDuration_, \\\"L73\\\");\\n\\n // Set immutable states\\n lToken = LToken(lTokenAddress_);\\n underlyingToken = IERC20(address(lToken.underlying()));\\n lockedHardCap = lockedHardCap_;\\n maxDistributedLDY = maxDistributedLDY_;\\n minLockDuration = minLockDuration_;\\n maxLockDuration = maxLockDuration_;\\n vestingDuration = vestingDuration_;\\n maxWeight = lockedHardCap * uint256(maxLockDuration);\\n }\\n\\n /**\\n * @notice Public implementation of Pausable's pausing and unpausing functions, but\\n * restricted to contract's owner.\\n */\\n function pause() public onlyOwner {\\n _pause();\\n }\\n\\n function unpause() public onlyOwner {\\n _unpause();\\n }\\n\\n /**\\n * @notice Updates the LDY token contract address.\\n * @dev As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE,\\n * this function allows the contract's owner to set the LDY token address once it\\n * becomes available.\\n * @param ldyTokenAddress Address of the LDY token contract.\\n */\\n function setLDYToken(address ldyTokenAddress) external onlyOwner {\\n // Prevent owner from changing the LDY address after Claim phase has started\\n require(!hasClaimPhaseStarted, \\\"L74\\\");\\n\\n // Set LDY token address\\n ldyToken = IERC20(ldyTokenAddress);\\n }\\n\\n /**\\n * @notice Closes the Deposit phase. After calling this function, account won't be\\n * able to lock additional underlying tokens anymore.\\n */\\n function endDepositPhase() external onlyOwner {\\n hasDepositPhaseEnded = true;\\n }\\n\\n /**\\n * @notice Opens the Claim phase. After calling this function, lockers will be able\\n * to start claiming their LDY rewards.\\n */\\n function startClaimPhase() external onlyOwner {\\n // Ensure Claim phase has not already started\\n require(!hasClaimPhaseStarted, \\\"L76\\\");\\n\\n // Ensure that LDY token address is available\\n require(address(ldyToken) != address(0), \\\"L77\\\");\\n\\n // Set Claim phase as started and store the start timestamp\\n hasClaimPhaseStarted = true;\\n claimPhaseStartTimestamp = block.timestamp;\\n }\\n\\n /**\\n * @notice Opens the Recovery phase. After calling this function, the contract owner\\n * will be able to recover remaining ERC20 tokens on the contract.\\n * Note that this won't close the Claim phase and lockers will still be able to claim\\n * their LDY rewards.\\n */\\n function startRecoveryPhase() external onlyOwner {\\n // Ensure Claim phase has started\\n require(hasClaimPhaseStarted, \\\"L79\\\");\\n\\n // Compute some durations in seconds\\n uint256 threeMonthsInSecond = 3 * 30 days;\\n uint256 vestingInSecond = uint256(vestingDuration) * 30 days;\\n uint256 maxLockInSecond = uint256(maxLockDuration) * 30 days;\\n\\n // Compute timestamp of vesting end + 3 months\\n uint256 afterVestingTimestamp = claimPhaseStartTimestamp +\\n vestingInSecond +\\n threeMonthsInSecond;\\n\\n // Ensure we are at least 3 months after the end of reward vesting\\n // This prevents owner from recovering LDY before lockers can claim their rewards\\n require(block.timestamp >= afterVestingTimestamp, \\\"L80\\\");\\n\\n // Compute end of maximum lock + 3 months\\n // Note that claimPhaseStartTimestamp is used for simplicity even if it can exist a time\\n // span between Deposit and Claim phases.\\n uint256 afterMaxLockTimestamp = claimPhaseStartTimestamp +\\n maxLockInSecond +\\n threeMonthsInSecond;\\n\\n // Ensure we are at least 3 months after the maximum lock end\\n // This prevents owner from recovering underlying tokens before lockers can unlock those\\n require(block.timestamp >= afterMaxLockTimestamp, \\\"L81\\\");\\n\\n // Set recovery phase as started\\n hasRecoveryPhaseStarted = true;\\n }\\n\\n /**\\n * @notice Recovers a specified amount of a given token address. Will revert if\\n * recovery phase has not started yet or if the contract doesn't hold enough tokens.\\n * @param tokenAddress The address of the token to recover.\\n * @param amount The amount of token to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\\n // Ensure recovery phase has started\\n require(hasRecoveryPhaseStarted, \\\"L82\\\");\\n\\n // Create a reference to token's contract\\n IERC20 tokenContract = IERC20(tokenAddress);\\n\\n // Ensure there is enough tokens to recover\\n require(tokenContract.balanceOf(address(this)) >= amount, \\\"L83\\\");\\n\\n // Transfer the recovered token amount to the sender (owner)\\n tokenContract.safeTransfer(msg.sender, amount);\\n }\\n\\n /**\\n * @notice Compute the total amount of LDY rewards that a given account is eligible to.\\n * @dev Note: This function neither considers vesting nor already claimed rewards.\\n * @param account The account to compute the eligible rewards of.\\n * @return The total amount of LDY rewards that the account is eligible to.\\n */\\n function eligibleRewardsOf(address account) public view returns (uint256) {\\n // Compute account's lock weight\\n uint256 lockerWeight = accountsLocks[account].amount * accountsLocks[account].duration;\\n\\n // Compute amount of LDY that this locker is eligible to\\n if (maxWeight == 0) return 0;\\n else return (maxDistributedLDY * lockerWeight) / maxWeight;\\n }\\n\\n /**\\n * @notice Allows locking a specified amount of underlying tokens for a given duration.\\n * By locking, an account became eligible to a portion of the distributed LDY rewards.\\n * @dev This function proxies LToken.deposit()\\n * @dev Lockers can extend their lock duration by calling this function again with a\\n * greater duration and 0 as amount.\\n * @param amount Amount of underlying tokens to lock.\\n * @param duration Duration of the lock (in months).\\n */\\n function lock(uint256 amount, uint8 duration) external whenNotPaused {\\n // Ensure Deposit phase has not ended yet\\n require(!hasDepositPhaseEnded, \\\"L84\\\");\\n\\n // Ensure account hasn't already unlocked a past lock\\n require(!accountsLocks[msg.sender].hasUnlocked, \\\"L71\\\");\\n\\n // Ensure lock duration is in valid range\\n require(duration >= minLockDuration && duration <= maxLockDuration, \\\"L85\\\");\\n\\n // Ensure it won't exceed the hardcap\\n require(totalLocked + amount <= uint256(lockedHardCap), \\\"L86\\\");\\n\\n // Increase account's locked amount\\n accountsLocks[msg.sender].amount += uint240(amount);\\n\\n // Increase total locked amount accordingly\\n totalLocked += amount;\\n\\n // Use existing lock duration if greater than the new one\\n uint8 existingDuration = accountsLocks[msg.sender].duration;\\n uint8 appliedDuration = existingDuration > duration ? existingDuration : duration;\\n\\n // Update account's lock duration\\n accountsLocks[msg.sender].duration = appliedDuration;\\n\\n // Update account's lock end timestamp\\n accountsLocks[msg.sender].lockEndTimestamp = uint40(\\n block.timestamp + uint40(appliedDuration) * 30 days\\n );\\n\\n // Emit a Lock event\\n emit Lock(msg.sender, amount, appliedDuration);\\n\\n // If amount is 0, skip deposit\\n if (amount == 0) return;\\n\\n // Transfer underlyingToken from account to contract\\n underlyingToken.safeTransferFrom(msg.sender, address(this), amount);\\n\\n // Deposit USDC in the L-Token contract\\n underlyingToken.safeApprove(address(lToken), amount);\\n lToken.deposit(amount);\\n }\\n\\n /**\\n * @notice Allows the caller to instaneously unlock its locked amount of underlying\\n * tokens.\\n * @dev In order to save some gas and time to users, frontends should propose this\\n * function to users only when it has been verified that it will not revert. They\\n * should propose the requestUnlock() function otherwise.\\n */\\n function instantUnlock() external whenNotPaused safeUnlock {\\n // Retrieve underlying tokens from the L-Token contract\\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\\n lToken.instantWithdrawal(unlockedAmount);\\n\\n // Transfer underlying tokens back to caller\\n underlyingToken.safeTransfer(msg.sender, unlockedAmount);\\n }\\n\\n /**\\n * @notice Allows the call to request for the unlocking of its locked amount of\\n * underlying tokens. The request will be automatically processed later.\\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\\n * paid by the withdrawer wallet.\\n */\\n function requestUnlock() external payable whenNotPaused safeUnlock {\\n // Put account in the unlock requests queue\\n unlockRequests.push(msg.sender);\\n\\n // Request underlying tokens to the L-Token contract\\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\\n lToken.requestWithdrawal{value: msg.value}(unlockedAmount);\\n }\\n\\n /**\\n * @notice Processes queued unlock requests until there is else no more requests,\\n * else not enough underlying tokens to continue.\\n */\\n function processUnlockRequests() external onlyOwner {\\n // Store the current request ID to process\\n uint256 processedId = unlockRequestsCursor;\\n\\n // Loop over remaining requests\\n while (processedId < unlockRequests.length) {\\n // Prevent OOG by stopping request processing if there is not enough gas left\\n // to continue the loop and properly end the function call.\\n if (gasleft() < 45000) break;\\n\\n // Retrieve the request account\\n address unlockAccount = unlockRequests[processedId];\\n\\n // Retrieve the unlocked amount\\n uint256 unlockAmount = accountsLocks[unlockAccount].amount;\\n\\n // If the request has already been processed, skip it\\n if (unlockAccount != address(0)) {\\n // If the contract doesn't hold enough underlying tokens to process the request, stop here\\n if (underlyingToken.balanceOf(address(this)) < unlockAmount) break;\\n\\n // Delete the request\\n delete unlockRequests[processedId];\\n\\n // Transfer underlying back to account\\n underlyingToken.safeTransfer(unlockAccount, unlockAmount);\\n }\\n\\n // Increment processed request ID\\n processedId++;\\n }\\n\\n // Write back the cursor in storage\\n unlockRequestsCursor = processedId;\\n }\\n\\n /**\\n * @notice Computes the amount of LDY rewards available to claim for a given account.\\n * @dev This function considers vesting and already claimed rewards.\\n * @param account The account to compute the available rewards of.\\n * @return The amount of LDY rewards available to claim.\\n */\\n function availableToClaim(address account) public view returns (uint256) {\\n // Compute total amount of rewards allocated to this locker\\n uint256 totalEligibleRewards = eligibleRewardsOf(account);\\n\\n // Compute vesting duration in seconds\\n uint256 vestingInSeconds = uint256(vestingDuration) * 30 days;\\n\\n // Compute elapsed months since claim phase started, and cap it to vesting duration\\n uint256 elapsedTime = block.timestamp - claimPhaseStartTimestamp;\\n if (elapsedTime > vestingInSeconds) elapsedTime = vestingInSeconds;\\n\\n // Compute total available to claim (proportionally to elapsed time)\\n uint256 totalAvailableToClaim = (totalEligibleRewards * elapsedTime) / vestingInSeconds;\\n\\n // Else return net claimable (available minus already claimed)\\n return totalAvailableToClaim - accountsLocks[account].claimedRewards;\\n }\\n\\n /// @notice Allows the caller to claim its available LDY rewards.\\n function claimRewards() external whenNotPaused {\\n // Ensure Claim phase has started\\n require(hasClaimPhaseStarted, \\\"L87\\\");\\n\\n // Compute claimable LDY rewards\\n uint256 claimableLDY = availableToClaim(msg.sender);\\n\\n // Increase account claimed amount accordingly\\n accountsLocks[msg.sender].claimedRewards += uint216(claimableLDY);\\n\\n // Transfer rewards to account\\n ldyToken.safeTransfer(msg.sender, claimableLDY);\\n }\\n}\\n\",\"keccak256\":\"0x52eeb33b4db1cca37de14e04dec818113149967b02982fc44c7969e05dcb5e27\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalOwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {GlobalOwner} from \\\"../GlobalOwner.sol\\\";\\n\\n/**\\n * @title GlobalOwnableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\\n * contract (see GlobalOwner.sol). This design facilitates centralized management\\n * of ownership for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalOwnableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\\n /**\\n * @notice The GlobalOwner contract the ownership will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalOwner private _globalOwner;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init_unchained(globalOwner_);\\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\\n // the initial _owner value, calling it would have no effect.\\n }\\n\\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\\n _globalOwner = GlobalOwner(globalOwner_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalOwner contract.\\n * @return The address of the GlobalOwner contract.\\n */\\n function globalOwner() public view returns (address) {\\n return address(_globalOwner);\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\\n * from the GlobalOwner contract instead.\\n * @return The address of the owner\\n */\\n function owner() public view override returns (address) {\\n return _globalOwner.owner();\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function transferOwnership(address newOwner) public view override onlyOwner {\\n newOwner; // Silence unused variable compiler warning\\n revert(\\\"L8\\\");\\n }\\n\\n /**\\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\\n * Ownership is managed by the GlobalOwner contract and must be modified there.\\n */\\n function renounceOwnership() public view override onlyOwner {\\n revert(\\\"L65\\\");\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x59c14d38e9e96d4f60cf2fd626c56e23928fce85107ac8d603dfdb90c9d81ec4\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalPausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {GlobalPause} from \\\"../GlobalPause.sol\\\";\\n\\n/**\\n * @title GlobalPausableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit pause state from the specified GlobalPause\\n * contract (see GlobalPause.sol). This design facilitates centralized management of\\n * pause state for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalPause state must be set at initialization-time and for evident\\n * security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalPausableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\\n /**\\n * @notice The GlobalPause contract the pause state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalPause private _globalPause;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalPause_ The address of the GlobalPause contract.\\n */\\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n }\\n\\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\\n _globalPause = GlobalPause(globalPause_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalPause contract.\\n * @return The address of the GlobalPause contract.\\n */\\n function globalPause() public view returns (address) {\\n return address(_globalPause);\\n }\\n\\n /**\\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\\n * from the GlobalPause contract instead.\\n * @return Whether the contract is paused or not.\\n */\\n function paused() public view virtual override returns (bool) {\\n return _globalPause.paused();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9ab501a2f6256a59e1712576423d4bc2fb97283aee704b87f1b3a749e85d1178\",\"license\":\"MIT\"},\"contracts/src/abstracts/GlobalRestrictableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalBlacklist} from \\\"../GlobalBlacklist.sol\\\";\\n\\n/**\\n * @title GlobalRestrictableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts will inherit blacklist state from the specified\\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\\n * centralized management of a blacklist for all the Ledgity Yield contracts.\\n *\\n * @dev Note: The _globalBlacklist state must be set at initialization-time and for\\n * evident security reasons cannot be changed afterwards.\\n *\\n * @dev For further details, see \\\"GlobalRestrictableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract GlobalRestrictableUpgradeable is Initializable {\\n /**\\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\\n * @dev This state is private so derived contracts cannot change its value.\\n */\\n GlobalBlacklist private _globalBlacklist;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n }\\n\\n function __GlobalRestrictable_init_unchained(\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\\n }\\n\\n /**\\n * @notice Retrieves the address of GlobalBlacklist contract.\\n * @return The address of the GlobalBlacklist contract.\\n */\\n function globalBlacklist() public view returns (address) {\\n return address(_globalBlacklist);\\n }\\n\\n /**\\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n */\\n modifier notBlacklisted(address account) {\\n require(isBlacklisted(account) == false, \\\"L9\\\");\\n _;\\n }\\n\\n /**\\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\\n * @param account Address to verify.\\n * @return Whether the account is blacklisted.\\n */\\n function isBlacklisted(address account) internal view returns (bool) {\\n return _globalBlacklist.isBlacklisted(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xb2413fea06f7221472d88b7d4f9be6e6a4efd8935e0b6857077667e6c881a9ea\",\"license\":\"MIT\"},\"contracts/src/abstracts/InvestUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Contracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"./GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"./GlobalRestrictableUpgradeable.sol\\\";\\nimport \\\"./base/BaseUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../abstracts/RecoverableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport {APRHistory as APRH} from \\\"../libs/APRHistory.sol\\\";\\nimport {SUD} from \\\"../libs/SUD.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title InvestUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with utilities to manage an invested token,\\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\\n *\\n * @dev Intuition:\\n * This contract primarily exists for code splitting and reusability. It unburdens the\\n * LToken contract code, making it easier to understand and maintain.\\n *\\n * This contract is generic because it may be used in the LDYStaking contract in the future.\\n *\\n * @dev Definitions:\\n * - Investment: The act of depositing or investing tokens into the contract.\\n * - Investment period: Time between the start of an investment or the last rewards\\n * distribution for an account to the present.\\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\\n * distributed between investment periods.\\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\\n *\\n * @dev Derived contract must:\\n * - Set invested token during initialization\\n * - Implement _investmentOf() function\\n * - Implement _distributeRewards() function (optional)\\n *\\n * @dev For further details, see \\\"InvestmentUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract InvestUpgradeable is BaseUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using APRH for APRH.Pack[];\\n\\n /**\\n * @notice Represents an account's investment period.\\n * @param timestamp The timestamp of the most recent rewards distribution.\\n * @param ref The reference of the last APR checkpoint at that timestamp.\\n */\\n struct InvestmentPeriod {\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n APRH.Reference ref;\\n }\\n\\n /**\\n * @notice Represents the investment details of an account.\\n * @param period The current investment period of the account.\\n * @param virtualBalance May hold a part of account rewards until they are claimed.\\n */\\n struct AccountDetails {\\n InvestmentPeriod period;\\n uint256 virtualBalance;\\n }\\n\\n /// @notice Holds a reference to the invested token's contract.\\n IERC20Upgradeable private _invested;\\n\\n /// @notice Holds investment details of each account.\\n mapping(address => AccountDetails) internal accountsDetails;\\n\\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\\n APRH.Pack[] private _aprHistory;\\n\\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\\n mapping(address => address) public rewardsRedirectsFromTo;\\n mapping(address => address[]) public rewardsRedirectsToFrom;\\n\\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\\n bool private _isClaiming;\\n\\n /**\\n * @notice Emitted to inform listeners about a change in the APR's value.\\n * @param newAPRUD7x3 The new APR in UD7x3 format.\\n */\\n event APRChangeEvent(uint16 newAPRUD7x3);\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param invested_ The address of the invested token contract.\\n */\\n function __Invest_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n address invested_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __Invest_init_unchained(invested_);\\n }\\n\\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\\n // Set invested token\\n _invested = IERC20Upgradeable(invested_);\\n\\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\\n // of an empty APR history\\n _aprHistory.setAPR(0);\\n }\\n\\n /**\\n * @notice Retrieves the reference to the invested token contract.\\n * @return The reference to the invested token contract.\\n */\\n function invested() public view returns (IERC20Upgradeable) {\\n return _invested;\\n }\\n\\n /**\\n * @notice Updates the investment APR. Restricted to owner.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(uint16 aprUD7x3) public onlyOwner {\\n _aprHistory.setAPR(aprUD7x3);\\n emit APRChangeEvent(aprUD7x3);\\n }\\n\\n /**\\n * @notice Retrieves the most recently set APR.\\n * @return The current APR in UD7x3 format.\\n */\\n function getAPR() public view returns (uint16) {\\n return _aprHistory.getAPR();\\n }\\n\\n /**\\n * @notice Enables redirection of rewards from one account to another.\\n * @param from The address of the account to redirect rewards from.\\n * @param to The address of the account to redirect rewards to.\\n */\\n function startRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure the address is not already redirecting rewards\\n require(rewardsRedirectsFromTo[from] == address(0), \\\"L62\\\");\\n\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L12\\\");\\n require(to != address(0), \\\"L13\\\");\\n\\n // Ensure 'from' and 'to' addresses are distinct\\n require(from != to, \\\"L14\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L15\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Activate rewards redirection\\n rewardsRedirectsFromTo[from] = to;\\n rewardsRedirectsToFrom[to].push(from);\\n }\\n\\n /**\\n * @notice Disable an active rewards redirection.\\n * @param from The address of the account to stop redirecting rewards from.\\n * @param to The address of the account to stop redirecting rewards to.\\n */\\n function stopRewardsRedirection(\\n address from,\\n address to\\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\\n // Ensure neither 'from' nor 'to' are the zero address\\n require(from != address(0), \\\"L16\\\");\\n require(to != address(0), \\\"L17\\\");\\n\\n // Ensure function caller is either the owner or the 'from' address\\n require(_msgSender() == owner() || _msgSender() == from, \\\"L18\\\");\\n\\n // Ensure a rewards redirection was active\\n require(rewardsRedirectsFromTo[from] == to, \\\"L19\\\");\\n\\n // Distribute current rewards and reset investment periods of both accounts\\n _beforeInvestmentChange(from, true);\\n _beforeInvestmentChange(to, true);\\n\\n // Retrieve 'from' index in the redirection array of 'to'\\n int256 fromIndex = -1;\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\\n if (rewardsRedirectsToFrom[to][i] == from) {\\n fromIndex = int256(i);\\n break;\\n }\\n }\\n\\n // fromIndex should never be -1 at this point\\n assert(fromIndex >= 0);\\n\\n // Deactivate rewards redirection\\n rewardsRedirectsFromTo[from] = address(0);\\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\\n rewardsRedirectsToFrom[to].length - 1\\n ];\\n rewardsRedirectsToFrom[to].pop();\\n }\\n\\n /**\\n * @notice Retrieves the total amount of tokens invested by the given account.\\n * @dev Derived contracts must implement this function.\\n * @param account The account to get the investment of.\\n * @return The total amount of tokens invested by the given account.\\n */\\n function _investmentOf(address account) internal view virtual returns (uint256);\\n\\n /**\\n * @notice Distributes a specified amount of rewards to a given account.\\n * @dev Derived contracts may optionally implement this function.\\n * @dev Implementations must return true to indicate a successful distribution, and\\n * false otherwise. If it returns false, the rewards will be added to the account's\\n * virtual balance, in order to be claimed later.\\n * @param account The account to claim the rewards of.\\n * @param amount The amount of rewards to claim.\\n * @return Whether the rewards distribution was successfull.\\n */\\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\\n account; // Silence unused variables warning\\n amount;\\n return false;\\n }\\n\\n /**\\n * @notice Computes the rewards accrued over a specified period of time, based on a\\n * given APR and amount of invested tokens.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param beginTimestamp The moment the period commenced.\\n * @param endTimestamp The moment the period concluded.\\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\\n * @param investedAmount The amount of tokens deposited/invested during the period.\\n * @return The amount of rewards generated during the period.\\n */\\n function _calculatePeriodRewards(\\n uint40 beginTimestamp,\\n uint40 endTimestamp,\\n uint16 aprUD7x3,\\n uint256 investedAmount\\n ) internal view returns (uint256) {\\n // Cache invested token's decimals number\\n uint256 d = SUD.decimalsOf(address(invested()));\\n\\n // Compute the number of elapsed years\\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\\n\\n // Compute the growth in invested amount (thanks to rewards)\\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\\n\\n // Compute and return the rewards\\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\\n return SUD.toAmount(rewardsSUD, d);\\n }\\n\\n /**\\n * @notice Computes the sum of given account's invested amount, plus invested amount\\n * of all accounts that recursively redirect rewards to this account.\\n * @param account The account to calculate the deep investment of.\\n * @return deepInvestedAmount The deep invested amount.\\n */\\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\\n // Consider account's direct investment\\n deepInvestedAmount += _investmentOf(account);\\n\\n // But also the deep investments of all accounts redirecting rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\\n * @dev For further details, see \\\"InvestUpgradeable > Rewards calculation\\\" section of\\n * the whitepaper.\\n * @param account The account to calculate the unclaimed rewards of.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\\n */\\n function _rewardsOf(\\n address account,\\n bool autocompound\\n ) internal view returns (uint256 rewards) {\\n // Retrieve account's investment details\\n AccountDetails memory details = accountsDetails[account];\\n\\n // Retrieve account's deep invested amount\\n uint256 investedAmount = _deepInvestmentOf(account);\\n\\n // Return 0 if the account has never invested or has no invested amount\\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\\n\\n // Retrieve reference and data of APR checkpoint at which started investment period\\n APRH.Reference memory currRef = details.period.ref;\\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\\n\\n // Retrieve reference of latest APR checkpoint\\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\\n\\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\\n // See \\\"InvestUpgradeable > Rewards calculation > 1)\\\" section of the whitepaper\\n rewards = details.virtualBalance;\\n\\n // If start checkpoint is not the latest one\\n if (!APRH.eq(currRef, latestRef)) {\\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // 2) Calculate rewards from investment period start to next checkpoint\\n // See \\\"InvestUpgradeable > Rewards calculation > 2)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n\\n // 3) Calculate rewards for each crossed pair of checkpoints\\n // See \\\"InvestUpgradeable > Rewards calculation > 3)\\\" section of the whitepaper\\n while (true) {\\n // Set next checkpoint as the current one\\n currRef = nextRef;\\n currCheckpoint = nextCheckpoint;\\n\\n // Break if current checkpoint is the latest one\\n if (APRH.eq(currRef, latestRef)) break;\\n\\n // Else, retrieve the new next checkpoint\\n nextRef = APRH.incrementReference(currRef);\\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\\n\\n // Calculate rewards between the current pair of checkpoints\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n nextCheckpoint.timestamp,\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n\\n // 4) Calculate rewards from the latest checkpoint to now\\n // See \\\"InvestUpgradeable > Rewards calculation > 4)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n currCheckpoint.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n } else {\\n // 2.bis) Calculate rewards from investment period start to now\\n // See \\\"InvestUpgradeable > Rewards calculation > 2.bis)\\\" section of the whitepaper\\n rewards += _calculatePeriodRewards(\\n details.period.timestamp,\\n uint40(block.timestamp),\\n currCheckpoint.aprUD7x3,\\n investedAmount + (autocompound ? rewards : 0)\\n );\\n }\\n }\\n\\n /**\\n * @notice Recursively resets the investment period of the specified account and of\\n * all accounts that directly or indirectly redirect rewards to this account.\\n * @param account The account to deeply reset the investment period of.\\n */\\n function _deepResetInvestmentPeriodOf(address account) internal {\\n // Reset account investment period timestamp and APR checkpoint to latest ones\\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\\n\\n // Also reset the ones of all accounts that recursively redirect rewards to this account\\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\\n }\\n }\\n\\n /**\\n * @notice Hook to be invoked before the invested amount of an account changes. It\\n * ensures that rewards are distributed and that account's investment period is reset.\\n * @param account The account whose invested amount is going to change.\\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\\n */\\n function _beforeInvestmentChange(address account, bool autocompound) internal {\\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\\n // minted in LToken._distributeRewards(), this guards against infinite loop.\\n if (_isClaiming) return;\\n\\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\\n // As first call will treat both addresses, the second call would be redundant.\\n // Therefore, we skip accounts already processed in this block to save up some gas.\\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\\n\\n // If account redirects its rewards\\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\\n if (redirectRewardsTo != address(0)) {\\n // Call hook on redirection target (this will indirectly reset the investment\\n // of this source account) and return\\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\\n return;\\n }\\n\\n // Else, compute account's undistributed/unclaimed rewards\\n uint256 rewards = _rewardsOf(account, autocompound);\\n\\n // If there are some rewards\\n if (rewards > 0) {\\n // Try to distribute rewards to account\\n _isClaiming = true;\\n bool distributed = _distributeRewards(account, rewards);\\n _isClaiming = false;\\n\\n // If rewards have not been distributed, accumulate them in account's virtual balance\\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\\n }\\n\\n // Finally, deeply reset investment period of the account\\n _deepResetInvestmentPeriodOf(account);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x62af366fd32223f266d27c26fa74b0ba818ef277a62aa27a00f9000531841079\",\"license\":\"MIT\"},\"contracts/src/abstracts/RecoverableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n// Conracts\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"./GlobalOwnableUpgradeable.sol\\\";\\n\\n// Libraries\\nimport {SafeERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\n\\n// Interfaces\\nimport {IERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @title RecoverableUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Derived contracts are provided with helpers functions that allow recovering\\n * assets accidentally sent to them.\\n *\\n * @dev Note: This abstract contract currently supports only ERC20 tokens. Derived\\n * contracts currently do not implement necessary functions to receive Ether or\\n * ERC721/ERC1155 tokens.\\n *\\n * @dev For further details, see \\\"RecoverableUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n */\\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\\n __GlobalOwnable_init(globalOwner_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Recoverable_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Recovers a specified amount of a given token address. Will fail if the\\n * contract doesn't hold enough tokens.\\n * @param tokenAddress The address of the token to recover.\\n * @param amount The amount of token to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\\n // Ensure the specified amount is not zero\\n require(amount > 0, \\\"L10\\\");\\n\\n // Create a reference to token's contract\\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\\n\\n // Ensure there is enough token to recover\\n require(tokenContract.balanceOf(address(this)) >= amount, \\\"L11\\\");\\n\\n // Transfer the recovered token amount to the sender\\n tokenContract.safeTransfer(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x00079960b44569f62b9dbccbe7c082b15e13fd769c721fad14c0b2cf36af1a59\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {UUPSUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\nimport {GlobalOwnableUpgradeable} from \\\"../GlobalOwnableUpgradeable.sol\\\";\\nimport {GlobalRestrictableUpgradeable} from \\\"../GlobalRestrictableUpgradeable.sol\\\";\\nimport {RecoverableUpgradeable} from \\\"../RecoverableUpgradeable.sol\\\";\\n\\n/**\\n * @title BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contract acts as a base for numerous contracts contract in this\\n * codebase, minimizing code repetition and enhancing readability and maintainability.\\n *\\n * @dev For further details, see \\\"Base\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract BaseUpgradeable is\\n Initializable,\\n UUPSUpgradeable,\\n GlobalOwnableUpgradeable,\\n GlobalPausableUpgradeable,\\n GlobalRestrictableUpgradeable,\\n RecoverableUpgradeable\\n{\\n /**\\n * @notice Prevents implementation contract from being initialized as recommended by\\n * OpenZeppelin.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\\n * @custom:oz-upgrades-unsafe-allow constructor\\n */\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n */\\n function __Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_\\n ) internal onlyInitializing {\\n __UUPSUpgradeable_init();\\n __GlobalOwnable_init(globalOwner_);\\n __Pausable_init();\\n __GlobalPausable_init_unchained(globalPause_);\\n __GlobalRestrictable_init_unchained(globalBlacklist_);\\n __Recoverable_init_unchained();\\n }\\n\\n function __Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\\n * global owner. It is called by the proxy contract during an upgrade.\\n * @param newImplementation The address of the new implementation contract.\\n */\\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x076f9babfcc47adaa8fbecf462fa1a6f301b0397ddf59c86b6d297608fcf8106\",\"license\":\"MIT\"},\"contracts/src/abstracts/base/ERC20BaseUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {ERC20Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\\\";\\nimport {ERC20PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport \\\"./BaseUpgradeable.sol\\\";\\nimport {GlobalPausableUpgradeable} from \\\"../GlobalPausableUpgradeable.sol\\\";\\n\\n/**\\n * @title ERC20BaseUpgradeable\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This abstract contracts is an extension of BaseUpgradeable intended to be used\\n * as a base for ERC20 tokens contracts.\\n *\\n * @dev For further details, see \\\"ERC20BaseUpgradeable\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nabstract contract ERC20BaseUpgradeable is\\n ERC20Upgradeable,\\n BaseUpgradeable,\\n ERC20PausableUpgradeable\\n{\\n /**\\n * @notice Initializer functions of the contract. They replace the constructor()\\n * function in the context of upgradeable contracts.\\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\\n * @param globalOwner_ The address of the GlobalOwner contract.\\n * @param globalPause_ The address of the GlobalPause contract.\\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\\n * @param name_ The display name of the token.\\n * @param symbol_ The symbol of the token.\\n */\\n function __ERC20Base_init(\\n address globalOwner_,\\n address globalPause_,\\n address globalBlacklist_,\\n string memory name_,\\n string memory symbol_\\n ) internal onlyInitializing {\\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\\n __ERC20_init(name_, symbol_);\\n __ERC20Pausable_init_unchained();\\n }\\n\\n function __ERC20Base_init_unchained() internal onlyInitializing {}\\n\\n /**\\n * @notice Required override of paused() which is implemented by both\\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\\n * state from the GlobalPause contract.\\n * @inheritdoc GlobalPausableUpgradeable\\n */\\n function paused()\\n public\\n view\\n virtual\\n override(GlobalPausableUpgradeable, PausableUpgradeable)\\n returns (bool)\\n {\\n return GlobalPausableUpgradeable.paused();\\n }\\n\\n /**\\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\\n * The ERC20PausableUpgradeable version is preferred because it also checks that\\n * the contract is not paused before allowing the transfer.\\n * @inheritdoc ERC20PausableUpgradeable\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n )\\n internal\\n virtual\\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\\n whenNotPaused\\n notBlacklisted(from)\\n notBlacklisted(to)\\n {\\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add\\n * new variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xf7cbb57bea04cbd394d05a4b216e06c84ba82e35e674042d699a813edd6e50da\",\"license\":\"MIT\"},\"contracts/src/interfaces/ITransfersListener.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\ninterface ITransfersListener {\\n function onLTokenTransfer(address from, address to, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0xb71129e8db615bfc1601206027a7056547b997dd2d9aacd9d2aec00508a412c7\",\"license\":\"MIT\"},\"contracts/src/libs/APRHistory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title APRHistory\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice This library offers utilities to efficiently maintain on chain, the history of\\n * an APR (Annual Percentage Rate). Each entry in this history is called a \\\"checkpoint\\\".\\n *\\n * @dev Intuition:\\n * Each checkpoint in an APR history consists in two data:\\n * - the creation timestamp\\n * - the APR at that time\\n *\\n * Given that reads and writes to storage slots are among the most costly operations in\\n * Solidity, this library provides a way to store those data on chain in a way that\\n * minimizes the number of used storage slots.\\n *\\n * Instead of storing each checkpoint in a separate storage slot, this library\\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\\n *\\n * @dev Definitions:\\n * - Checkpoint: A record of an APR change\\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\\n * - History: A dynamic array of packs\\n * - Reference: A storage pointer to a checkpoint in the APR history\\n * - CheckpointData: An in-memory representation of a checkpoint data\\n *\\n * @dev Limitation: This library can accommodate APRs only up to 65.536%. This is however\\n * sufficient for APR in LToken contract, which is expected to remain below 10%.\\n *\\n * @dev For further details, see \\\"APRHistory\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary APRHistory {\\n /**\\n * @notice Represents data of a checkpoint extracted from the on-chain history.\\n * For on-chain representation see \\\"Pack\\\" struct.\\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\\n * @param timestamp Timestamp of the checkpoint's creation.\\n */\\n struct CheckpointData {\\n uint16 aprUD7x3; // Allows up to 65.536%\\n uint40 timestamp; // Supports dates up to 20/02/36812\\n }\\n\\n /**\\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\\n * @param aprsUD7x3 Array of checkpoints' APRs.\\n * @param timestamps Array of checkpoints' timestamps.\\n * @param cursor Index of the next checkpoint to be written.\\n */\\n struct Pack {\\n uint16[4] aprsUD7x3;\\n uint40[4] timestamps;\\n uint32 cursor;\\n }\\n\\n /**\\n * @notice Represents a storage pointer to a specific checkpoint in the history.\\n * @param packIndex Index of the pack the checkpoint belongs to.\\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\\n */\\n struct Reference {\\n uint256 packIndex;\\n uint32 cursorIndex;\\n }\\n\\n /**\\n * @notice Compares two checkpoints references.\\n * @param ref1 The first reference to compare.\\n * @param ref2 The second reference to compare.\\n * @return Whether the two references points to the same checkpoint.\\n */\\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\\n }\\n\\n /**\\n * @notice Returns the reference of the checkpoint that should come right after the\\n * referenced checkpoint in the APR history.\\n * @param ref The reference to be incremented.\\n * @return The incremented reference.\\n */\\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L1\\\");\\n\\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\\n //\\n // Else, return ref of next slot in current pack\\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\\n }\\n\\n /**\\n * @notice Extracts checkpoint data from a given reference and in APR history.\\n * @param self The APR history to extract the checkpoint from.\\n * @param ref The reference of the checkpoint data to extract.\\n * @return The extracted checkpoint's data.\\n */\\n function getDataFromReference(\\n Pack[] storage self,\\n Reference memory ref\\n ) public view returns (CheckpointData memory) {\\n // Ensure cursor index of the given ref is within valid range [0, 3]\\n require(ref.cursorIndex <= 3, \\\"L2\\\");\\n\\n // Ensure pack index of the given ref exists in history\\n require(ref.packIndex < self.length, \\\"L3\\\");\\n\\n // Retrieve pack data from history\\n Pack memory pack = self[ref.packIndex];\\n\\n // Ensure cursor index of the given ref has been written\\n require(ref.cursorIndex < pack.cursor, \\\"L4\\\");\\n\\n // Build and return the checkpoint data\\n return\\n CheckpointData({\\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\\n timestamp: pack.timestamps[ref.cursorIndex]\\n });\\n }\\n\\n /**\\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\\n * @param self The history to extract the reference from.\\n * @return The reference of the latest checkpoint.\\n */\\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\\n // Ensure the given history is not empty\\n require(self.length != 0, \\\"L5\\\");\\n\\n // Retrieve latest pack's index and cursor\\n uint256 packIndex = self.length - 1;\\n uint32 packCursor = self[packIndex].cursor;\\n\\n // If this is the first pack ever, ensure it is not empty\\n if (packIndex == 0) require(packCursor != 0, \\\"L6\\\");\\n\\n // If the pack is empty, return ref of previous pack's latest slot\\n if (packCursor == 0) return Reference(packIndex - 1, 3);\\n //\\n // Else, return ref of previous slot in current pack\\n else return Reference(packIndex, packCursor - 1);\\n }\\n\\n /**\\n * @notice Appends a new empty pack to the end of the given APR history array.\\n * @param self The APR history to append an empty to.\\n */\\n function newBlankPack(Pack[] storage self) internal {\\n // If history is not empty, ensure the latest pack is full\\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \\\"L7\\\");\\n\\n // Push a new blank pack to the history array\\n self.push(\\n Pack({\\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\\n cursor: 0\\n })\\n );\\n }\\n\\n /**\\n * @notice Write a new APR checkpoint at the end of the given history array.\\n * @param self The array of packs to write the new checkpoint to.\\n * @param aprUD7x3 The new APR in UD7x3 format.\\n */\\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\\n // Determine the reference where the new checkpoint should be written\\n Reference memory newRef = self.length == 0\\n ? Reference(0, 0)\\n : incrementReference(getLatestReference(self));\\n\\n // If pack to be written doesn't exist yet, push a new blank pack in history\\n if (newRef.packIndex >= self.length) newBlankPack(self);\\n\\n // Retrieve the pack where the new checkpoint will be stored\\n Pack memory pack = self[newRef.packIndex];\\n\\n // Add new checkpoint's data to the pack\\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\\n\\n // Increment the pack's cursor\\n pack.cursor++;\\n\\n // Write the updated pack in storage\\n self[newRef.packIndex] = pack;\\n }\\n\\n /**\\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\\n * @param self The history array to read APR from.\\n * @return The latest checkpoint's APR.\\n */\\n function getAPR(Pack[] storage self) public view returns (uint16) {\\n // Retrieve the latest checkpoint data\\n Reference memory ref = getLatestReference(self);\\n CheckpointData memory data = getDataFromReference(self, ref);\\n\\n // Return the latest checkpoint's APR\\n return data.aprUD7x3;\\n }\\n}\\n\",\"keccak256\":\"0x7954e7130fb127fc8cd81fb852de2df2eda688c0d4ef6cdd9280809cdf2815c3\",\"license\":\"MIT\"},\"contracts/src/libs/SUD.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {IERC20MetadataUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @title SUD\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice SUD serves as an intermediary number format for calculations within this\\n * codebase. It ensures consistency and reduces precision losses. This library\\n * facilitates conversions between various number formats and the SUD format.\\n *\\n * @dev Intuition:\\n * This codebase employs UD (unsigned decimal fixed-point numbers) format to represent\\n * both percentage rates and tokens amounts.\\n *\\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\\n * the decimals() value of the involved tokens.\\n *\\n * Three challenges arise from this:\\n * 1) To compute values together, it's essential that they are in the same format\\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\\n * precision loss (because division shrinks). A common approach is to scale up and\\n * down values by a few decimals before and after performing calculations.\\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\\n * be shrinked in case token's decimals number is in [0, 2].\\n *\\n * To address these challenges, this library provides the SUD format, which acts as a\\n * consistent and scaled intermediate format to perform calculations on.\\n *\\n * SUD is an acronym for either \\\"Scaled UD\\\" or \\\"Safe UD\\\".\\n *\\n * @dev Definitions:\\n * - Integer: A number without fractional part, e.g., block.timestamp\\n * - UD: A decimal unsigned fixed-point number. The \\\"UD\\\" notation is inspired from\\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\\n * - Amount: An UD with an unknown (at writing time) repartition of digits between\\n * integral and fractional parts. Represents a token amount.\\n * - Rate: An UD with 7 integral digits and 3 fractional ones (a.k.a UD7x3).\\n * Represents a percentage rate.\\n * - SUD: An UD with 3 more decimals than the involved rate or amount with the highest\\n * decimals number. As rates are represented by UD7x3, a SUD number has at least 6\\n * decimals (3+3) and so ranges from UD71x6 to UD0x77 formats.\\n * Used as an intermediate format to perform calculations.\\n *\\n * @dev This library provides utilities to perform the following conversions:\\n * - Amount <--> SUD\\n * - Rate (UD7x3) <--> SUD\\n * - Integer <--> SUD\\n *\\n * @dev Why scaling by 3 decimals?\\n * - It provides an adequate degree of precision for this codebase,\\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\\n * the involved token's decimal number.\\n *\\n * @dev Optimization note: The functions of this library are not set to external because\\n * incorporating them directly into contracts is more gas-efficient. Given their minimal\\n * size and frequent usage in the InvestUpgradeable, LDYStaking, and LToken contracts,\\n * any bytecode savings from making them external are negated by the additional bytecode\\n * required for external calls to this library.\\n * The can be observed by comparing the output of `pnpm cc:size` when those functions's\\n * visibility is set to external or internal.\\n *\\n * @dev Precision note: While this library mitigates precision loss during calculations\\n * on UD numbers, it's important to note that tokens with lower decimal counts and supply\\n * inherently suffer more from precision loss. Conversely, tokens with higher decimal\\n * counts and supply will experience less precision loss.\\n *\\n * @dev For further details, see \\\"SUD\\\" section of whitepaper.\\n * @custom:security-contact security@ledgity.com\\n */\\nlibrary SUD {\\n /**\\n * @notice Retrieves decimals number of the given ERC20 contract address.\\n * @param tokenAddress The address to retrieve decimals number from.\\n * @return decimals The decimals number of the given ERC20 contract address.\\n */\\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\\n }\\n\\n /**\\n * @notice Convert a given token amount into SUD format.\\n * @param nAmount The token amount to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The amount in SUD format\\n */\\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\\n\\n // Else return a number with decimals+3 fractional digits\\n return nAmount * 10 ** 3;\\n }\\n\\n /**\\n * @notice Convert a given SUD number into token amount format.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nAmount The number in amount format\\n */\\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** 3;\\n }\\n\\n /**\\n * @notice Converts a given UD7x3 rate into SUD format.\\n * @param nUD7x3 The UD7x3 rate to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The rate in SUD format.\\n */\\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return nUD7x3 * 10 ** 3;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return nUD7x3 * 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given SUD number into a UD7x3 rate.\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nUD7x3 The number in UD7x3 rate format.\\n */\\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 3;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** decimals;\\n }\\n\\n /**\\n * @notice Converts a given integer into SUD format.\\n * @param n The integer to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return nSUD The integer in SUD format.\\n */\\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\\n // If token decimals < 3, return a UD71x6 number\\n if (decimals < 3) return n * 10 ** 6;\\n\\n // Else, return a number with decimals+3 fractional digits\\n return n * 10 ** (decimals + 3);\\n }\\n\\n /**\\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\\n * @param nSUD The SUD number to convert.\\n * @param decimals The decimals number of the involved ERC20 token.\\n * @return n The SUD number as an integer.\\n */\\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\\n // If token decimals < 3, convert from a UD71x6 number\\n if (decimals < 3) return nSUD / 10 ** 6;\\n\\n // Else, convert from a number with decimals+3 fractional digits\\n return nSUD / 10 ** (decimals + 3);\\n }\\n}\\n\",\"keccak256\":\"0x70c9f9f0ae1875fae1ae6c06a3cd73d405f5a6e2b74493690c044d86acf21f79\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6101806040523480156200001257600080fd5b50604051620024943803806200249483398101604081905262000035916200022d565b620000403362000186565b6001805460ff60a01b1916815560ff841610156200008b5760405162461bcd60e51b8152602060048201526003602482015262261b9960e91b60448201526064015b60405180910390fd5b8160ff168360ff161115620000c95760405162461bcd60e51b81526020600482015260036024820152624c373360e81b604482015260640162000082565b6001600160a01b03861661012081905260408051636f307dc360e01b81529051636f307dc3916004808201926020929091908290030181865afa15801562000115573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013b91906200029f565b6001600160a01b03166101405260a0849052608085905260ff80841660c05282811660e081905290821661010052620001759085620002c6565b6101605250620002f2945050505050565b600180546001600160a01b0319169055620001ad81620001b0602090811b620017cb17901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620001ad57600080fd5b805160ff811681146200022857600080fd5b919050565b60008060008060008060c087890312156200024757600080fd5b8651620002548162000200565b6020880151604089015191975095509350620002736060880162000216565b9250620002836080880162000216565b91506200029360a0880162000216565b90509295509295509295565b600060208284031215620002b257600080fd5b8151620002bf8162000200565b9392505050565b8082028115828204841417620002ec57634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e051610100516101205161014051610160516120be620003d6600039600081816106b301528181611740015261177101526000818161043a015281816110460152818161136301528181611398015281816114e1015261159201526000818161023101528181610c9601528181610fdd015281816113ba01526113f50152600081816103d401528181610816015261090301526000818161067f0152818161093701526111300152600081816106e701526110ff01526000818161054b015261118d0152600081816102a4015261179601526120be6000f3fe60806040526004361061021a5760003560e01c8063747dbf06116101235780639c3857a7116100ab578063e30c39781161006f578063e30c397814610709578063ed75a3ab14610727578063eddd21431461073d578063f2fde38b14610752578063fe98988a1461077257600080fd5b80639c3857a714610643578063a1568d4b14610658578063a16cdbb11461066d578063a8b0bb83146106a1578063d6a298e9146106d557600080fd5b80638980f11f116100f25780638980f11f146105b15780638acc764e146105d15780638da5cb5b146105e65780638f6a32a214610604578063998e42421461062357600080fd5b8063747dbf061461053957806379ba50971461056d578063828ed046146105825780638456cb591461059c57600080fd5b8063276a5699116101a6578063568914121161017557806356891412146104bb57806356e19a2c146104d15780635c975abb146104d95780635fd6218914610504578063715018a61461052457600080fd5b8063276a56991461045c57806330de5b3c14610471578063372500ab146104915780633f4ba83a146104a657600080fd5b80630da45188116101ed5780630da451881461038c57806312f60d3c146103ac5780631514617e146103c257806321ed3195146104085780632495a5991461042857600080fd5b8063010ee1841461021f578063085defc4146102705780630b441d6f146102925780630beea97a146102d4575b600080fd5b34801561022b57600080fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027c57600080fd5b5061029061028b366004611dfa565b610792565b005b34801561029e57600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610267565b3480156102e057600080fd5b506103436102ef366004611dfa565b600360205260009081526040902080546001909101546001600160f01b0382169160ff600160f01b8204811692600160f81b90920416906001600160d81b0381169064ffffffffff600160d81b9091041685565b604080516001600160f01b03909616865260ff9094166020860152911515928401929092526001600160d81b03909116606083015264ffffffffff16608082015260a001610267565b34801561039857600080fd5b506102c66103a7366004611dfa565b6107ff565b3480156103b857600080fd5b506102c660065481565b3480156103ce57600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610267565b34801561041457600080fd5b50600254610253906001600160a01b031681565b34801561043457600080fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b34801561046857600080fd5b506102906108b1565b34801561047d57600080fd5b5061025361048c366004611e15565b610a20565b34801561049d57600080fd5b50610290610a4a565b3480156104b257600080fd5b50610290610b07565b3480156104c757600080fd5b506102c660045481565b610290610b19565b3480156104e557600080fd5b50600154600160a01b900460ff165b6040519015158152602001610267565b34801561051057600080fd5b506005546104f49062010000900460ff1681565b34801561053057600080fd5b50610290610cff565b34801561054557600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561057957600080fd5b50610290610d11565b34801561058e57600080fd5b506005546104f49060ff1681565b3480156105a857600080fd5b50610290610d88565b3480156105bd57600080fd5b506102906105cc366004611e2e565b610d98565b3480156105dd57600080fd5b50610290610e97565b3480156105f257600080fd5b506000546001600160a01b0316610253565b34801561061057600080fd5b506005546104f490610100900460ff1681565b34801561062f57600080fd5b5061029061063e366004611e58565b61106f565b34801561064f57600080fd5b5061029061145f565b34801561066457600080fd5b506102906115da565b34801561067957600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b3480156106ad57600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e157600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b34801561071557600080fd5b506001546001600160a01b0316610253565b34801561073357600080fd5b506102c660085481565b34801561074957600080fd5b506102906115f1565b34801561075e57600080fd5b5061029061076d366004611dfa565b61168a565b34801561077e57600080fd5b506102c661078d366004611dfa565b6116fb565b61079a61181b565b600554610100900460ff16156107dd5760405162461bcd60e51b8152602060048201526003602482015262130dcd60ea1b60448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008061080b836116fb565b9050600061083f60ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b90506000600654426108519190611ec1565b90508181111561085e5750805b60008261086b8386611ea4565b6108759190611ed4565b6001600160a01b0387166000908152600360205260409020600101549091506108a7906001600160d81b031682611ec1565b9695505050505050565b6108b961181b565b600554610100900460ff166108f65760405162461bcd60e51b81526020600482015260036024820152624c373960e81b60448201526064016107d4565b6276a700600061092c60ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b9050600061096060ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b9050600083836006546109739190611ef6565b61097d9190611ef6565b9050804210156109b55760405162461bcd60e51b815260206004820152600360248201526204c38360ec1b60448201526064016107d4565b600084836006546109c69190611ef6565b6109d09190611ef6565b905080421015610a085760405162461bcd60e51b81526020600482015260036024820152624c383160e81b60448201526064016107d4565b50506005805462ff0000191662010000179055505050565b60078181548110610a3057600080fd5b6000918252602090912001546001600160a01b0316905081565b610a52611875565b600554610100900460ff16610a8f5760405162461bcd60e51b81526020600482015260036024820152624c383760e81b60448201526064016107d4565b6000610a9a336107ff565b33600090815260036020526040812060010180549293508392909190610aca9084906001600160d81b0316611f09565b82546001600160d81b039182166101009390930a928302919092021990911617905550600254610b04906001600160a01b031633836118c2565b50565b610b0f61181b565b610b17611925565b565b610b21611875565b3360009081526003602052604090206001015442600160d81b90910464ffffffffff161115610b785760405162461bcd60e51b81526020600482015260036024820152620986c760eb1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff1615610bc55760405162461bcd60e51b81526020600482015260036024820152624c363960e81b60448201526064016107d4565b336000908152600360205260409020546001600160f01b0316610c105760405162461bcd60e51b815260206004820152600360248201526204c37360ec1b60448201526064016107d4565b336000818152600360205260409081902080546001600160f81b0316600160f81b17815560078054600181019091557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b031916909317909255905490516313dccf3d60e31b81526001600160f01b0390911660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639ee679e89034906024016000604051808303818588803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050505050565b610d0761181b565b610b17600061197a565b60015433906001600160a01b03168114610d7f5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107d4565b610b048161197a565b610d9061181b565b610b17611993565b610da061181b565b60055462010000900460ff16610dde5760405162461bcd60e51b8152602060048201526003602482015262261c1960e91b60448201526064016107d4565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015610e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4a9190611f30565b1015610e7e5760405162461bcd60e51b81526020600482015260036024820152624c383360e81b60448201526064016107d4565b610e926001600160a01b03821633846118c2565b505050565b610e9f611875565b3360009081526003602052604090206001015442600160d81b90910464ffffffffff161115610ef65760405162461bcd60e51b81526020600482015260036024820152620986c760eb1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff1615610f435760405162461bcd60e51b81526020600482015260036024820152624c363960e81b60448201526064016107d4565b336000908152600360205260409020546001600160f01b0316610f8e5760405162461bcd60e51b815260206004820152600360248201526204c37360ec1b60448201526064016107d4565b33600090815260036020526040908190208054600160f81b6001600160f81b038216179091559051634134bee960e01b81526001600160f01b0390911660048201819052906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634134bee990602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b50610b049250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016905033836118c2565b611077611875565b60055460ff16156110b05760405162461bcd60e51b8152602060048201526003602482015262130e0d60ea1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff16156110fd5760405162461bcd60e51b81526020600482015260036024820152624c373160e81b60448201526064016107d4565b7f000000000000000000000000000000000000000000000000000000000000000060ff168160ff161015801561115957507f000000000000000000000000000000000000000000000000000000000000000060ff168160ff1611155b61118b5760405162461bcd60e51b81526020600482015260036024820152624c383560e81b60448201526064016107d4565b7f0000000000000000000000000000000000000000000000000000000000000000826004546111ba9190611ef6565b11156111ee5760405162461bcd60e51b8152602060048201526003602482015262261c1b60e91b60448201526064016107d4565b33600090815260036020526040812080548492906112169084906001600160f01b0316611f49565b92506101000a8154816001600160f01b0302191690836001600160f01b03160217905550816004600082825461124c9190611ef6565b90915550503360009081526003602052604081205460ff600160f01b909104811691908316821161127d578261127f565b815b336000908152600360205260409020805460ff60f01b1916600160f01b60ff8416908102919091179091559091506112ba9062278d00611f69565b6112cb9064ffffffffff1642611ef6565b3360008181526003602052604090819020600101805464ffffffffff94909416600160d81b026001600160d81b039094169390931790925590517f111750799d4c0d4634f6bcaaeb8596889f0c1c9c36ae900df00617890266ac5990611340908790859091825260ff16602082015260400190565b60405180910390a2836000036113565750505050565b61138b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330876119d6565b6113df6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000086611a14565b60405163b6b55f2560e01b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561144157600080fd5b505af1158015611455573d6000803e3d6000fd5b5050505050505050565b61146761181b565b6008545b6007548110156115d55761afc85a106115d55760006007828154811061149357611493611f92565b60009182526020808320909101546001600160a01b031680835260039091526040909120549091506001600160f01b031681156115c1576040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190611f30565b1015611561575050600855565b6007838154811061157457611574611f92565b600091825260209091200180546001600160a01b03191690556115c17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031683836118c2565b826115cb81611fa8565b935050505061146b565b600855565b6115e261181b565b6005805460ff19166001179055565b6115f961181b565b600554610100900460ff16156116375760405162461bcd60e51b8152602060048201526003602482015262261b9b60e91b60448201526064016107d4565b6002546001600160a01b03166116755760405162461bcd60e51b81526020600482015260036024820152624c373760e81b60448201526064016107d4565b6005805461ff00191661010017905542600655565b61169261181b565b600180546001600160a01b0383166001600160a01b031990911681179091556116c36000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6001600160a01b03811660009081526003602052604081205481906117339060ff600160f01b820416906001600160f01b0316611fc1565b6001600160f01b031690507f000000000000000000000000000000000000000000000000000000000000000060000361176f5750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000006117ba827f0000000000000000000000000000000000000000000000000000000000000000611ea4565b6117c49190611ed4565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314610b175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d4565b600154600160a01b900460ff1615610b175760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107d4565b6040516001600160a01b038316602482015260448101829052610e9290849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611b29565b61192d611bfe565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600180546001600160a01b0319169055610b04816117cb565b61199b611875565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861195d3390565b6040516001600160a01b0380851660248301528316604482015260648101829052611a0e9085906323b872dd60e01b906084016118ee565b50505050565b801580611a8e5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8c9190611f30565b155b611af95760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016107d4565b6040516001600160a01b038316602482015260448101829052610e9290849063095ea7b360e01b906064016118ee565b6000611b7e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611c4e9092919063ffffffff16565b9050805160001480611b9f575080806020019051810190611b9f9190611ff3565b610e925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107d4565b600154600160a01b900460ff16610b175760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107d4565b6060611c5d8484600085611c65565b949350505050565b606082471015611cc65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107d4565b600080866001600160a01b03168587604051611ce29190612039565b60006040518083038185875af1925050503d8060008114611d1f576040519150601f19603f3d011682016040523d82523d6000602084013e611d24565b606091505b5091509150611d3587838387611d40565b979650505050505050565b60608315611daf578251600003611da8576001600160a01b0385163b611da85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107d4565b5081611c5d565b611c5d8383815115611dc45781518083602001fd5b8060405162461bcd60e51b81526004016107d49190612055565b80356001600160a01b0381168114611df557600080fd5b919050565b600060208284031215611e0c57600080fd5b6117c482611dde565b600060208284031215611e2757600080fd5b5035919050565b60008060408385031215611e4157600080fd5b611e4a83611dde565b946020939093013593505050565b60008060408385031215611e6b57600080fd5b82359150602083013560ff81168114611e8357600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417611ebb57611ebb611e8e565b92915050565b81810381811115611ebb57611ebb611e8e565b600082611ef157634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115611ebb57611ebb611e8e565b6001600160d81b03818116838216019080821115611f2957611f29611e8e565b5092915050565b600060208284031215611f4257600080fd5b5051919050565b6001600160f01b03818116838216019080821115611f2957611f29611e8e565b64ffffffffff818116838216028082169190828114611f8a57611f8a611e8e565b505092915050565b634e487b7160e01b600052603260045260246000fd5b600060018201611fba57611fba611e8e565b5060010190565b6001600160f01b03828116828216818102831692918115828504821417611fea57611fea611e8e565b50505092915050565b60006020828403121561200557600080fd5b815180151581146117c457600080fd5b60005b83811015612030578181015183820152602001612018565b50506000910152565b6000825161204b818460208701612015565b9190910192915050565b6020815260008251806020840152612074816040850160208701612015565b601f01601f1916919091016040019291505056fea26469706673582212202a37a88e33ffa644edcc3b49f00c58b84ed0924056f9587575327201e01a6b6564736f6c63430008120033", - "deployedBytecode": "0x60806040526004361061021a5760003560e01c8063747dbf06116101235780639c3857a7116100ab578063e30c39781161006f578063e30c397814610709578063ed75a3ab14610727578063eddd21431461073d578063f2fde38b14610752578063fe98988a1461077257600080fd5b80639c3857a714610643578063a1568d4b14610658578063a16cdbb11461066d578063a8b0bb83146106a1578063d6a298e9146106d557600080fd5b80638980f11f116100f25780638980f11f146105b15780638acc764e146105d15780638da5cb5b146105e65780638f6a32a214610604578063998e42421461062357600080fd5b8063747dbf061461053957806379ba50971461056d578063828ed046146105825780638456cb591461059c57600080fd5b8063276a5699116101a6578063568914121161017557806356891412146104bb57806356e19a2c146104d15780635c975abb146104d95780635fd6218914610504578063715018a61461052457600080fd5b8063276a56991461045c57806330de5b3c14610471578063372500ab146104915780633f4ba83a146104a657600080fd5b80630da45188116101ed5780630da451881461038c57806312f60d3c146103ac5780631514617e146103c257806321ed3195146104085780632495a5991461042857600080fd5b8063010ee1841461021f578063085defc4146102705780630b441d6f146102925780630beea97a146102d4575b600080fd5b34801561022b57600080fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027c57600080fd5b5061029061028b366004611dfa565b610792565b005b34801561029e57600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610267565b3480156102e057600080fd5b506103436102ef366004611dfa565b600360205260009081526040902080546001909101546001600160f01b0382169160ff600160f01b8204811692600160f81b90920416906001600160d81b0381169064ffffffffff600160d81b9091041685565b604080516001600160f01b03909616865260ff9094166020860152911515928401929092526001600160d81b03909116606083015264ffffffffff16608082015260a001610267565b34801561039857600080fd5b506102c66103a7366004611dfa565b6107ff565b3480156103b857600080fd5b506102c660065481565b3480156103ce57600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610267565b34801561041457600080fd5b50600254610253906001600160a01b031681565b34801561043457600080fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b34801561046857600080fd5b506102906108b1565b34801561047d57600080fd5b5061025361048c366004611e15565b610a20565b34801561049d57600080fd5b50610290610a4a565b3480156104b257600080fd5b50610290610b07565b3480156104c757600080fd5b506102c660045481565b610290610b19565b3480156104e557600080fd5b50600154600160a01b900460ff165b6040519015158152602001610267565b34801561051057600080fd5b506005546104f49062010000900460ff1681565b34801561053057600080fd5b50610290610cff565b34801561054557600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561057957600080fd5b50610290610d11565b34801561058e57600080fd5b506005546104f49060ff1681565b3480156105a857600080fd5b50610290610d88565b3480156105bd57600080fd5b506102906105cc366004611e2e565b610d98565b3480156105dd57600080fd5b50610290610e97565b3480156105f257600080fd5b506000546001600160a01b0316610253565b34801561061057600080fd5b506005546104f490610100900460ff1681565b34801561062f57600080fd5b5061029061063e366004611e58565b61106f565b34801561064f57600080fd5b5061029061145f565b34801561066457600080fd5b506102906115da565b34801561067957600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b3480156106ad57600080fd5b506102c67f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e157600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b34801561071557600080fd5b506001546001600160a01b0316610253565b34801561073357600080fd5b506102c660085481565b34801561074957600080fd5b506102906115f1565b34801561075e57600080fd5b5061029061076d366004611dfa565b61168a565b34801561077e57600080fd5b506102c661078d366004611dfa565b6116fb565b61079a61181b565b600554610100900460ff16156107dd5760405162461bcd60e51b8152602060048201526003602482015262130dcd60ea1b60448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60008061080b836116fb565b9050600061083f60ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b90506000600654426108519190611ec1565b90508181111561085e5750805b60008261086b8386611ea4565b6108759190611ed4565b6001600160a01b0387166000908152600360205260409020600101549091506108a7906001600160d81b031682611ec1565b9695505050505050565b6108b961181b565b600554610100900460ff166108f65760405162461bcd60e51b81526020600482015260036024820152624c373960e81b60448201526064016107d4565b6276a700600061092c60ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b9050600061096060ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00611ea4565b9050600083836006546109739190611ef6565b61097d9190611ef6565b9050804210156109b55760405162461bcd60e51b815260206004820152600360248201526204c38360ec1b60448201526064016107d4565b600084836006546109c69190611ef6565b6109d09190611ef6565b905080421015610a085760405162461bcd60e51b81526020600482015260036024820152624c383160e81b60448201526064016107d4565b50506005805462ff0000191662010000179055505050565b60078181548110610a3057600080fd5b6000918252602090912001546001600160a01b0316905081565b610a52611875565b600554610100900460ff16610a8f5760405162461bcd60e51b81526020600482015260036024820152624c383760e81b60448201526064016107d4565b6000610a9a336107ff565b33600090815260036020526040812060010180549293508392909190610aca9084906001600160d81b0316611f09565b82546001600160d81b039182166101009390930a928302919092021990911617905550600254610b04906001600160a01b031633836118c2565b50565b610b0f61181b565b610b17611925565b565b610b21611875565b3360009081526003602052604090206001015442600160d81b90910464ffffffffff161115610b785760405162461bcd60e51b81526020600482015260036024820152620986c760eb1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff1615610bc55760405162461bcd60e51b81526020600482015260036024820152624c363960e81b60448201526064016107d4565b336000908152600360205260409020546001600160f01b0316610c105760405162461bcd60e51b815260206004820152600360248201526204c37360ec1b60448201526064016107d4565b336000818152600360205260409081902080546001600160f81b0316600160f81b17815560078054600181019091557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b031916909317909255905490516313dccf3d60e31b81526001600160f01b0390911660048201819052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639ee679e89034906024016000604051808303818588803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050505050565b610d0761181b565b610b17600061197a565b60015433906001600160a01b03168114610d7f5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107d4565b610b048161197a565b610d9061181b565b610b17611993565b610da061181b565b60055462010000900460ff16610dde5760405162461bcd60e51b8152602060048201526003602482015262261c1960e91b60448201526064016107d4565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015610e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4a9190611f30565b1015610e7e5760405162461bcd60e51b81526020600482015260036024820152624c383360e81b60448201526064016107d4565b610e926001600160a01b03821633846118c2565b505050565b610e9f611875565b3360009081526003602052604090206001015442600160d81b90910464ffffffffff161115610ef65760405162461bcd60e51b81526020600482015260036024820152620986c760eb1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff1615610f435760405162461bcd60e51b81526020600482015260036024820152624c363960e81b60448201526064016107d4565b336000908152600360205260409020546001600160f01b0316610f8e5760405162461bcd60e51b815260206004820152600360248201526204c37360ec1b60448201526064016107d4565b33600090815260036020526040908190208054600160f81b6001600160f81b038216179091559051634134bee960e01b81526001600160f01b0390911660048201819052906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634134bee990602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b50610b049250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016905033836118c2565b611077611875565b60055460ff16156110b05760405162461bcd60e51b8152602060048201526003602482015262130e0d60ea1b60448201526064016107d4565b33600090815260036020526040902054600160f81b900460ff16156110fd5760405162461bcd60e51b81526020600482015260036024820152624c373160e81b60448201526064016107d4565b7f000000000000000000000000000000000000000000000000000000000000000060ff168160ff161015801561115957507f000000000000000000000000000000000000000000000000000000000000000060ff168160ff1611155b61118b5760405162461bcd60e51b81526020600482015260036024820152624c383560e81b60448201526064016107d4565b7f0000000000000000000000000000000000000000000000000000000000000000826004546111ba9190611ef6565b11156111ee5760405162461bcd60e51b8152602060048201526003602482015262261c1b60e91b60448201526064016107d4565b33600090815260036020526040812080548492906112169084906001600160f01b0316611f49565b92506101000a8154816001600160f01b0302191690836001600160f01b03160217905550816004600082825461124c9190611ef6565b90915550503360009081526003602052604081205460ff600160f01b909104811691908316821161127d578261127f565b815b336000908152600360205260409020805460ff60f01b1916600160f01b60ff8416908102919091179091559091506112ba9062278d00611f69565b6112cb9064ffffffffff1642611ef6565b3360008181526003602052604090819020600101805464ffffffffff94909416600160d81b026001600160d81b039094169390931790925590517f111750799d4c0d4634f6bcaaeb8596889f0c1c9c36ae900df00617890266ac5990611340908790859091825260ff16602082015260400190565b60405180910390a2836000036113565750505050565b61138b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330876119d6565b6113df6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000086611a14565b60405163b6b55f2560e01b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561144157600080fd5b505af1158015611455573d6000803e3d6000fd5b5050505050505050565b61146761181b565b6008545b6007548110156115d55761afc85a106115d55760006007828154811061149357611493611f92565b60009182526020808320909101546001600160a01b031680835260039091526040909120549091506001600160f01b031681156115c1576040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611530573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115549190611f30565b1015611561575050600855565b6007838154811061157457611574611f92565b600091825260209091200180546001600160a01b03191690556115c17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031683836118c2565b826115cb81611fa8565b935050505061146b565b600855565b6115e261181b565b6005805460ff19166001179055565b6115f961181b565b600554610100900460ff16156116375760405162461bcd60e51b8152602060048201526003602482015262261b9b60e91b60448201526064016107d4565b6002546001600160a01b03166116755760405162461bcd60e51b81526020600482015260036024820152624c373760e81b60448201526064016107d4565b6005805461ff00191661010017905542600655565b61169261181b565b600180546001600160a01b0383166001600160a01b031990911681179091556116c36000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6001600160a01b03811660009081526003602052604081205481906117339060ff600160f01b820416906001600160f01b0316611fc1565b6001600160f01b031690507f000000000000000000000000000000000000000000000000000000000000000060000361176f5750600092915050565b7f00000000000000000000000000000000000000000000000000000000000000006117ba827f0000000000000000000000000000000000000000000000000000000000000000611ea4565b6117c49190611ed4565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314610b175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d4565b600154600160a01b900460ff1615610b175760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107d4565b6040516001600160a01b038316602482015260448101829052610e9290849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611b29565b61192d611bfe565b6001805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600180546001600160a01b0319169055610b04816117cb565b61199b611875565b6001805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861195d3390565b6040516001600160a01b0380851660248301528316604482015260648101829052611a0e9085906323b872dd60e01b906084016118ee565b50505050565b801580611a8e5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8c9190611f30565b155b611af95760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016107d4565b6040516001600160a01b038316602482015260448101829052610e9290849063095ea7b360e01b906064016118ee565b6000611b7e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611c4e9092919063ffffffff16565b9050805160001480611b9f575080806020019051810190611b9f9190611ff3565b610e925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107d4565b600154600160a01b900460ff16610b175760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107d4565b6060611c5d8484600085611c65565b949350505050565b606082471015611cc65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107d4565b600080866001600160a01b03168587604051611ce29190612039565b60006040518083038185875af1925050503d8060008114611d1f576040519150601f19603f3d011682016040523d82523d6000602084013e611d24565b606091505b5091509150611d3587838387611d40565b979650505050505050565b60608315611daf578251600003611da8576001600160a01b0385163b611da85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107d4565b5081611c5d565b611c5d8383815115611dc45781518083602001fd5b8060405162461bcd60e51b81526004016107d49190612055565b80356001600160a01b0381168114611df557600080fd5b919050565b600060208284031215611e0c57600080fd5b6117c482611dde565b600060208284031215611e2757600080fd5b5035919050565b60008060408385031215611e4157600080fd5b611e4a83611dde565b946020939093013593505050565b60008060408385031215611e6b57600080fd5b82359150602083013560ff81168114611e8357600080fd5b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417611ebb57611ebb611e8e565b92915050565b81810381811115611ebb57611ebb611e8e565b600082611ef157634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115611ebb57611ebb611e8e565b6001600160d81b03818116838216019080821115611f2957611f29611e8e565b5092915050565b600060208284031215611f4257600080fd5b5051919050565b6001600160f01b03818116838216019080821115611f2957611f29611e8e565b64ffffffffff818116838216028082169190828114611f8a57611f8a611e8e565b505092915050565b634e487b7160e01b600052603260045260246000fd5b600060018201611fba57611fba611e8e565b5060010190565b6001600160f01b03828116828216818102831692918115828504821417611fea57611fea611e8e565b50505092915050565b60006020828403121561200557600080fd5b815180151581146117c457600080fd5b60005b83811015612030578181015183820152602001612018565b50506000910152565b6000825161204b818460208701612015565b9190910192915050565b6020815260008251806020840152612074816040850160208701612015565b601f01601f1916919091016040019291505056fea26469706673582212202a37a88e33ffa644edcc3b49f00c58b84ed0924056f9587575327201e01a6b6564736f6c63430008120033", - "devdoc": { - "author": "Lila Rest (https://lila.rest)", - "custom:security-contact": "security@ledgity.comsecurity@ledgity.com", - "details": "Intuition Lifecycle of a lockdrop pool is composed by 3 main phases: 1) Deposit: During this phase, users can lock their underlying tokens. 2) Claim: During this phase, users can claim their LDY rewards. 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract. Transitioning between two phases is manually triggered by contract's owner. To ensure fair usage of this power and prevent potential misuse: - the Recovery phase cannot start before 3 months after the end of rewards vesting, - the Recovery phase cannot start before 3 months after the maximum lock end. Finally, note that this contract proxies main L-Token contract's functions: - lock() --> deposit() - instantUnlock() --> instantWithdrawal() - requestUnlock() --> requestWithdrawal() This design enables users to interact with the PreMining contract in a similar fashion to the L-Token contract. Definitions: - Locker: An account that has locked underlying tokens in the pool. ", - "events": { - "Paused(address)": { - "details": "Emitted when the pause is triggered by `account`." - }, - "Unpaused(address)": { - "details": "Emitted when the pause is lifted by `account`." - } - }, - "kind": "dev", - "methods": { - "acceptOwnership()": { - "details": "The new owner accepts the ownership transfer." - }, - "availableToClaim(address)": { - "details": "This function considers vesting and already claimed rewards.", - "params": { - "account": "The account to compute the available rewards of." - }, - "returns": { - "_0": "The amount of LDY rewards available to claim." - } - }, - "constructor": { - "params": { - "lTokenAddress_": "Address of the L-Token contract to use.", - "lockedHardCap_": "Maximum total amount of L-Tokens that can be locked.", - "maxDistributedLDY_": "Amount of LDY to be distributed to lockers.", - "maxLockDuration_": "Maximum possible lock duration (in months).", - "minLockDuration_": "Minimum possible lock duration (in months).", - "vestingDuration_": "Duration of LDY rewards vesting (in months)." - } - }, - "eligibleRewardsOf(address)": { - "details": "Note: This function neither considers vesting nor already claimed rewards.", - "params": { - "account": "The account to compute the eligible rewards of." - }, - "returns": { - "_0": "The total amount of LDY rewards that the account is eligible to." - } - }, - "instantUnlock()": { - "details": "In order to save some gas and time to users, frontends should propose this function to users only when it has been verified that it will not revert. They should propose the requestUnlock() function otherwise." - }, - "lock(uint256,uint8)": { - "details": "This function proxies LToken.deposit()Lockers can extend their lock duration by calling this function again with a greater duration and 0 as amount.", - "params": { - "amount": "Amount of underlying tokens to lock.", - "duration": "Duration of the lock (in months)." - } - }, - "owner()": { - "details": "Returns the address of the current owner." - }, - "paused()": { - "details": "Returns true if the contract is paused, and false otherwise." - }, - "pendingOwner()": { - "details": "Returns the address of the pending owner." - }, - "recoverERC20(address,uint256)": { - "params": { - "amount": "The amount of token to recover.", - "tokenAddress": "The address of the token to recover." - } - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." - }, - "requestUnlock()": { - "details": "The sender must attach 0.003 ETH to pre-pay the future processing gas fees paid by the withdrawer wallet." - }, - "setLDYToken(address)": { - "details": "As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE, this function allows the contract's owner to set the LDY token address once it becomes available.", - "params": { - "ldyTokenAddress": "Address of the LDY token contract." - } - }, - "transferOwnership(address)": { - "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner." - } - }, - "title": "PreMining", - "version": 1 - }, - "userdoc": { - "events": { - "Lock(address,uint256,uint8)": { - "notice": "Emitted to inform about a new lock/deposit." - } - }, - "kind": "user", - "methods": { - "accountsLocks(address)": { - "notice": "Holds lockers' participations informations." - }, - "availableToClaim(address)": { - "notice": "Computes the amount of LDY rewards available to claim for a given account." - }, - "claimPhaseStartTimestamp()": { - "notice": "Holds the timestamp at which the Claim phase started." - }, - "claimRewards()": { - "notice": "Allows the caller to claim its available LDY rewards." - }, - "constructor": { - "notice": "This constructor function etches the lockdrop terms in immutable states. Ensuring that those terms cannot be modified after deployment." - }, - "eligibleRewardsOf(address)": { - "notice": "Compute the total amount of LDY rewards that a given account is eligible to." - }, - "endDepositPhase()": { - "notice": "Closes the Deposit phase. After calling this function, account won't be able to lock additional underlying tokens anymore." - }, - "hasClaimPhaseStarted()": { - "notice": "Holds whether the Claim phase has started." - }, - "hasDepositPhaseEnded()": { - "notice": "Holds whether the Deposit phase has ended." - }, - "hasRecoveryPhaseStarted()": { - "notice": "Holds whether the Recovery phase has started." - }, - "instantUnlock()": { - "notice": "Allows the caller to instaneously unlock its locked amount of underlying tokens." - }, - "lToken()": { - "notice": "Holds a reference to the locked L-Token contract." - }, - "ldyToken()": { - "notice": "Holds a reference to the LDY token contract." - }, - "lock(uint256,uint8)": { - "notice": "Allows locking a specified amount of underlying tokens for a given duration. By locking, an account became eligible to a portion of the distributed LDY rewards." - }, - "lockedHardCap()": { - "notice": "Holds the maximum total amount of L-Tokens that can be locked." - }, - "maxDistributedLDY()": { - "notice": "Holds the amount of LDY to be distributed to lockers." - }, - "maxLockDuration()": { - "notice": "Holds the maximum possible lock duration (in months)." - }, - "maxWeight()": { - "notice": "Holds the max pool weight." - }, - "minLockDuration()": { - "notice": "Holds the minimum possible lock duration (in months)." - }, - "pause()": { - "notice": "Public implementation of Pausable's pausing and unpausing functions, but restricted to contract's owner." - }, - "processUnlockRequests()": { - "notice": "Processes queued unlock requests until there is else no more requests, else not enough underlying tokens to continue." - }, - "recoverERC20(address,uint256)": { - "notice": "Recovers a specified amount of a given token address. Will revert if recovery phase has not started yet or if the contract doesn't hold enough tokens." - }, - "requestUnlock()": { - "notice": "Allows the call to request for the unlocking of its locked amount of underlying tokens. The request will be automatically processed later." - }, - "setLDYToken(address)": { - "notice": "Updates the LDY token contract address." - }, - "startClaimPhase()": { - "notice": "Opens the Claim phase. After calling this function, lockers will be able to start claiming their LDY rewards." - }, - "startRecoveryPhase()": { - "notice": "Opens the Recovery phase. After calling this function, the contract owner will be able to recover remaining ERC20 tokens on the contract. Note that this won't close the Claim phase and lockers will still be able to claim their LDY rewards." - }, - "totalLocked()": { - "notice": "Holds the total amount of locked underlying tokens." - }, - "underlyingToken()": { - "notice": "Holds a reference to the L-Token underlying stablecoin." - }, - "unlockRequests(uint256)": { - "notice": "Holds an ordered queue of accounts that requested to unlock their tokens." - }, - "unlockRequestsCursor()": { - "notice": "Holds the index of the first request in the queue (a.k.a, next one to be processed)." - }, - "vestingDuration()": { - "notice": "Holds the duration of LDY rewards vesting (in months)." - } - }, - "notice": "PreMining pool contract, allowing accounts to lock underlying tokens in a pre-defined L-Token contract, over a given duration (in months), in exchange of vested LDY rewards. ", - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 2904, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3017, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "_pendingOwner", - "offset": 0, - "slot": "1", - "type": "t_address" - }, - { - "astId": 3110, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "_paused", - "offset": 20, - "slot": "1", - "type": "t_bool" - }, - { - "astId": 6877, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "ldyToken", - "offset": 0, - "slot": "2", - "type": "t_contract(IERC20)3865" - }, - { - "astId": 6883, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "accountsLocks", - "offset": 0, - "slot": "3", - "type": "t_mapping(t_address,t_struct(AccountLock)6847_storage)" - }, - { - "astId": 6886, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "totalLocked", - "offset": 0, - "slot": "4", - "type": "t_uint256" - }, - { - "astId": 6889, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "hasDepositPhaseEnded", - "offset": 0, - "slot": "5", - "type": "t_bool" - }, - { - "astId": 6892, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "hasClaimPhaseStarted", - "offset": 1, - "slot": "5", - "type": "t_bool" - }, - { - "astId": 6895, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "hasRecoveryPhaseStarted", - "offset": 2, - "slot": "5", - "type": "t_bool" - }, - { - "astId": 6898, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "claimPhaseStartTimestamp", - "offset": 0, - "slot": "6", - "type": "t_uint256" - }, - { - "astId": 6902, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "unlockRequests", - "offset": 0, - "slot": "7", - "type": "t_array(t_address)dyn_storage" - }, - { - "astId": 6905, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "unlockRequestsCursor", - "offset": 0, - "slot": "8", - "type": "t_uint256" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_array(t_address)dyn_storage": { - "base": "t_address", - "encoding": "dynamic_array", - "label": "address[]", - "numberOfBytes": "32" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(IERC20)3865": { - "encoding": "inplace", - "label": "contract IERC20", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_struct(AccountLock)6847_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => struct PreMining.AccountLock)", - "numberOfBytes": "32", - "value": "t_struct(AccountLock)6847_storage" - }, - "t_struct(AccountLock)6847_storage": { - "encoding": "inplace", - "label": "struct PreMining.AccountLock", - "members": [ - { - "astId": 6838, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "amount", - "offset": 0, - "slot": "0", - "type": "t_uint240" - }, - { - "astId": 6840, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "duration", - "offset": 30, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 6842, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "hasUnlocked", - "offset": 31, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 6844, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "claimedRewards", - "offset": 0, - "slot": "1", - "type": "t_uint216" - }, - { - "astId": 6846, - "contract": "contracts/src/PreMining.sol:PreMining", - "label": "lockEndTimestamp", - "offset": 27, - "slot": "1", - "type": "t_uint40" - } - ], - "numberOfBytes": "64" - }, - "t_uint216": { - "encoding": "inplace", - "label": "uint216", - "numberOfBytes": "27" - }, - "t_uint240": { - "encoding": "inplace", - "label": "uint240", - "numberOfBytes": "30" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint40": { - "encoding": "inplace", - "label": "uint40", - "numberOfBytes": "5" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/contracts/hardhat/deployments/localhost/USDC.json b/contracts/hardhat/deployments/localhost/USDC.json index 8f5e4a0f..1d1ea992 100644 --- a/contracts/hardhat/deployments/localhost/USDC.json +++ b/contracts/hardhat/deployments/localhost/USDC.json @@ -350,7 +350,7 @@ "type": "function" } ], - "transactionHash": "0x2dee40237482dd5ba09ac3cc502d06a26c861de72005b43a0fe144cff176ecbe", + "transactionHash": "0x67a8f6365ed7214c3f2115434a6643b9d2b3b4cb1f9ee12831c84263c53e1155", "receipt": { "to": null, "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", @@ -358,20 +358,24 @@ "transactionIndex": 0, "gasUsed": "762005", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x92052bec8f53ec2dd3f8c0847db15627e6c6b4bc74825291faa81a3daf151d38", - "transactionHash": "0x2dee40237482dd5ba09ac3cc502d06a26c861de72005b43a0fe144cff176ecbe", + "blockHash": "0x5e0e5013c22dc40265bc48ee502e58acdc5ab69528fc5e70e73e833661fc12ad", + "transactionHash": "0x67a8f6365ed7214c3f2115434a6643b9d2b3b4cb1f9ee12831c84263c53e1155", "logs": [], "blockNumber": 9, "cumulativeGasUsed": "762005", "status": 1, "byzantium": true }, - "args": ["Fake USDC", "USDC", 6], + "args": [ + "Fake USDC", + "USDC", + 6 + ], "numDeployments": 1, - "solcInputHash": "51ee222fb2f1beb1ef1977fa0bb4b538", - "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"}],\"name\":\"setDecimals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Destroys `amount` tokens from the caller. See {ERC20-_burn}.\"},\"burnFrom(address,uint256)\":{\"details\":\"Destroys `amount` tokens from `account`, deducting from the caller's allowance. See {ERC20-_burn} and {ERC20-allowance}. Requirements: - the caller must have allowance for ``accounts``'s tokens of at least `amount`.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setDecimals(uint8)\":{\"notice\":\"Used in tests to test different decimals scenarios.\"}},\"notice\":\"Used for testing purposes only. It represents: - a FIAT-based stablecoin when used to test the LToken contract, - the $LDY token when used to test the LDYStaking contract. This contract accept decimals as constructor argument, so it can be used to to easily test different decimals scenarios.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GenericERC20.sol\":\"GenericERC20\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/GenericERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/**\\n * @notice Used for testing purposes only.\\n * It represents:\\n * - a FIAT-based stablecoin when used to test the LToken contract,\\n * - the $LDY token when used to test the LDYStaking contract.\\n * This contract accept decimals as constructor argument, so it can be used to to\\n * easily test different decimals scenarios.\\n */\\ncontract GenericERC20 is ERC20, ERC20Burnable {\\n uint8 private _decimals;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) {\\n _decimals = decimals_;\\n }\\n\\n function mint(uint256 amount) public {\\n _mint(msg.sender, amount);\\n }\\n\\n function decimals() public view virtual override returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * Used in tests to test different decimals scenarios.\\n */\\n function setDecimals(uint8 decimals_) public {\\n _decimals = decimals_;\\n }\\n}\\n\",\"keccak256\":\"0x7a2266633eecc23497c13b0da770392e6479a41b726acda4252dcf5c32291ae2\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b5060405162000e8238038062000e82833981016040819052620000349162000139565b828260036200004483826200024d565b5060046200005382826200024d565b50506005805460ff191660ff93909316929092179091555062000319915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200009c57600080fd5b81516001600160401b0380821115620000b957620000b962000074565b604051601f8301601f19908116603f01168101908282118183101715620000e457620000e462000074565b816040528381526020925086838588010111156200010157600080fd5b600091505b8382101562000125578582018301518183018401529082019062000106565b600093810190920192909252949350505050565b6000806000606084860312156200014f57600080fd5b83516001600160401b03808211156200016757600080fd5b62000175878388016200008a565b945060208601519150808211156200018c57600080fd5b506200019b868287016200008a565b925050604084015160ff81168114620001b357600080fd5b809150509250925092565b600181811c90821680620001d357607f821691505b602082108103620001f457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200024857600081815260208120601f850160051c81016020861015620002235750805b601f850160051c820191505b8181101562000244578281556001016200022f565b5050505b505050565b81516001600160401b0381111562000269576200026962000074565b62000281816200027a8454620001be565b84620001fa565b602080601f831160018114620002b95760008415620002a05750858301515b600019600386901b1c1916600185901b17855562000244565b600085815260208120601f198616915b82811015620002ea57888601518255948401946001909101908401620002c9565b5085821015620003095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610b5980620003296000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a0712d6811610066578063a0712d6814610205578063a457c2d714610218578063a9059cbb1461022b578063dd62ed3e1461023e57600080fd5b806370a082311461019d57806379cc6790146101c65780637a1395aa146101d957806395d89b41146101fd57600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461017557806342966c681461018857600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610251565b60405161010f9190610967565b60405180910390f35b61012b6101263660046109d1565b6102e3565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b3660046109fb565b6102fd565b60055460405160ff909116815260200161010f565b61012b6101833660046109d1565b610321565b61019b610196366004610a37565b610343565b005b61013f6101ab366004610a50565b6001600160a01b031660009081526020819052604090205490565b61019b6101d43660046109d1565b610350565b61019b6101e7366004610a72565b6005805460ff191660ff92909216919091179055565b610102610369565b61019b610213366004610a37565b610378565b61012b6102263660046109d1565b610382565b61012b6102393660046109d1565b610402565b61013f61024c366004610a95565b610410565b60606003805461026090610ac8565b80601f016020809104026020016040519081016040528092919081815260200182805461028c90610ac8565b80156102d95780601f106102ae576101008083540402835291602001916102d9565b820191906000526020600020905b8154815290600101906020018083116102bc57829003601f168201915b5050505050905090565b6000336102f181858561043b565b60019150505b92915050565b60003361030b858285610560565b6103168585856105da565b506001949350505050565b6000336102f18185856103348383610410565b61033e9190610b02565b61043b565b61034d338261077e565b50565b61035b823383610560565b610365828261077e565b5050565b60606004805461026090610ac8565b61034d33826108a8565b600033816103908286610410565b9050838110156103f55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610316828686840361043b565b6000336102f18185856105da565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03831661049d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ec565b6001600160a01b0382166104fe5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ec565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061056c8484610410565b905060001981146105d457818110156105c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ec565b6105d4848484840361043b565b50505050565b6001600160a01b03831661063e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ec565b6001600160a01b0382166106a05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ec565b6001600160a01b038316600090815260208190526040902054818110156107185760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ec565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d4565b6001600160a01b0382166107de5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ec565b6001600160a01b038216600090815260208190526040902054818110156108525760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ec565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610553565b6001600160a01b0382166108fe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ec565b80600260008282546109109190610b02565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561099457858101830151858201604001528201610978565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146109cc57600080fd5b919050565b600080604083850312156109e457600080fd5b6109ed836109b5565b946020939093013593505050565b600080600060608486031215610a1057600080fd5b610a19846109b5565b9250610a27602085016109b5565b9150604084013590509250925092565b600060208284031215610a4957600080fd5b5035919050565b600060208284031215610a6257600080fd5b610a6b826109b5565b9392505050565b600060208284031215610a8457600080fd5b813560ff81168114610a6b57600080fd5b60008060408385031215610aa857600080fd5b610ab1836109b5565b9150610abf602084016109b5565b90509250929050565b600181811c90821680610adc57607f821691505b602082108103610afc57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102f757634e487b7160e01b600052601160045260246000fdfea2646970667358221220dd302236734f6646b35c5bd84b326ffbfb9bc3dc94309ee7b65e7a472fdd6ab664736f6c63430008120033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a0712d6811610066578063a0712d6814610205578063a457c2d714610218578063a9059cbb1461022b578063dd62ed3e1461023e57600080fd5b806370a082311461019d57806379cc6790146101c65780637a1395aa146101d957806395d89b41146101fd57600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461017557806342966c681461018857600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610251565b60405161010f9190610967565b60405180910390f35b61012b6101263660046109d1565b6102e3565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b3660046109fb565b6102fd565b60055460405160ff909116815260200161010f565b61012b6101833660046109d1565b610321565b61019b610196366004610a37565b610343565b005b61013f6101ab366004610a50565b6001600160a01b031660009081526020819052604090205490565b61019b6101d43660046109d1565b610350565b61019b6101e7366004610a72565b6005805460ff191660ff92909216919091179055565b610102610369565b61019b610213366004610a37565b610378565b61012b6102263660046109d1565b610382565b61012b6102393660046109d1565b610402565b61013f61024c366004610a95565b610410565b60606003805461026090610ac8565b80601f016020809104026020016040519081016040528092919081815260200182805461028c90610ac8565b80156102d95780601f106102ae576101008083540402835291602001916102d9565b820191906000526020600020905b8154815290600101906020018083116102bc57829003601f168201915b5050505050905090565b6000336102f181858561043b565b60019150505b92915050565b60003361030b858285610560565b6103168585856105da565b506001949350505050565b6000336102f18185856103348383610410565b61033e9190610b02565b61043b565b61034d338261077e565b50565b61035b823383610560565b610365828261077e565b5050565b60606004805461026090610ac8565b61034d33826108a8565b600033816103908286610410565b9050838110156103f55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610316828686840361043b565b6000336102f18185856105da565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03831661049d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ec565b6001600160a01b0382166104fe5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ec565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061056c8484610410565b905060001981146105d457818110156105c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ec565b6105d4848484840361043b565b50505050565b6001600160a01b03831661063e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ec565b6001600160a01b0382166106a05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ec565b6001600160a01b038316600090815260208190526040902054818110156107185760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ec565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d4565b6001600160a01b0382166107de5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ec565b6001600160a01b038216600090815260208190526040902054818110156108525760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ec565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610553565b6001600160a01b0382166108fe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ec565b80600260008282546109109190610b02565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561099457858101830151858201604001528201610978565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146109cc57600080fd5b919050565b600080604083850312156109e457600080fd5b6109ed836109b5565b946020939093013593505050565b600080600060608486031215610a1057600080fd5b610a19846109b5565b9250610a27602085016109b5565b9150604084013590509250925092565b600060208284031215610a4957600080fd5b5035919050565b600060208284031215610a6257600080fd5b610a6b826109b5565b9392505050565b600060208284031215610a8457600080fd5b813560ff81168114610a6b57600080fd5b60008060408385031215610aa857600080fd5b610ab1836109b5565b9150610abf602084016109b5565b90509250929050565b600181811c90821680610adc57607f821691505b602082108103610afc57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102f757634e487b7160e01b600052601160045260246000fdfea2646970667358221220dd302236734f6646b35c5bd84b326ffbfb9bc3dc94309ee7b65e7a472fdd6ab664736f6c63430008120033", + "solcInputHash": "1c94255f5edec71501da736e9b19ae5f", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"}],\"name\":\"setDecimals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(uint256)\":{\"details\":\"Destroys `amount` tokens from the caller. See {ERC20-_burn}.\"},\"burnFrom(address,uint256)\":{\"details\":\"Destroys `amount` tokens from `account`, deducting from the caller's allowance. See {ERC20-_burn} and {ERC20-allowance}. Requirements: - the caller must have allowance for ``accounts``'s tokens of at least `amount`.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"setDecimals(uint8)\":{\"notice\":\"Used in tests to test different decimals scenarios.\"}},\"notice\":\"Used for testing purposes only, and used to generate ABIs for Wagmi contracts calls. It represents: - a FIAT-based stablecoin when used to test the LToken contract, - the $LDY token when used to test the LDYStaking contract. This contract accept decimals as constructor argument, so it can be used to to easily test different decimals scenarios.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/src/GenericERC20.sol\":\"GenericERC20\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\\n * tokens and those that they have an allowance for, in a way that can be\\n * recognized off-chain (via event analysis).\\n */\\nabstract contract ERC20Burnable is Context, ERC20 {\\n /**\\n * @dev Destroys `amount` tokens from the caller.\\n *\\n * See {ERC20-_burn}.\\n */\\n function burn(uint256 amount) public virtual {\\n _burn(_msgSender(), amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\\n * allowance.\\n *\\n * See {ERC20-_burn} and {ERC20-allowance}.\\n *\\n * Requirements:\\n *\\n * - the caller must have allowance for ``accounts``'s tokens of at least\\n * `amount`.\\n */\\n function burnFrom(address account, uint256 amount) public virtual {\\n _spendAllowance(account, _msgSender(), amount);\\n _burn(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0x0d19410453cda55960a818e02bd7c18952a5c8fe7a3036e81f0d599f34487a7b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/src/GenericERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {ERC20} from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport {ERC20Burnable} from \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\\\";\\n\\n/**\\n * @notice Used for testing purposes only, and used to generate ABIs for Wagmi contracts calls.\\n * It represents:\\n * - a FIAT-based stablecoin when used to test the LToken contract,\\n * - the $LDY token when used to test the LDYStaking contract.\\n * This contract accept decimals as constructor argument, so it can be used to to\\n * easily test different decimals scenarios.\\n */\\ncontract GenericERC20 is ERC20, ERC20Burnable {\\n uint8 private _decimals;\\n\\n constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) {\\n _decimals = decimals_;\\n }\\n\\n function mint(uint256 amount) public {\\n _mint(msg.sender, amount);\\n }\\n\\n function decimals() public view virtual override returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * Used in tests to test different decimals scenarios.\\n */\\n function setDecimals(uint8 decimals_) public {\\n _decimals = decimals_;\\n }\\n}\\n\",\"keccak256\":\"0x6c041437008dd8d1dece8f784e02ad8c17a403dbde82f7dcb54abb39cd7b363a\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162000e8238038062000e82833981016040819052620000349162000139565b828260036200004483826200024d565b5060046200005382826200024d565b50506005805460ff191660ff93909316929092179091555062000319915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200009c57600080fd5b81516001600160401b0380821115620000b957620000b962000074565b604051601f8301601f19908116603f01168101908282118183101715620000e457620000e462000074565b816040528381526020925086838588010111156200010157600080fd5b600091505b8382101562000125578582018301518183018401529082019062000106565b600093810190920192909252949350505050565b6000806000606084860312156200014f57600080fd5b83516001600160401b03808211156200016757600080fd5b62000175878388016200008a565b945060208601519150808211156200018c57600080fd5b506200019b868287016200008a565b925050604084015160ff81168114620001b357600080fd5b809150509250925092565b600181811c90821680620001d357607f821691505b602082108103620001f457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200024857600081815260208120601f850160051c81016020861015620002235750805b601f850160051c820191505b8181101562000244578281556001016200022f565b5050505b505050565b81516001600160401b0381111562000269576200026962000074565b62000281816200027a8454620001be565b84620001fa565b602080601f831160018114620002b95760008415620002a05750858301515b600019600386901b1c1916600185901b17855562000244565b600085815260208120601f198616915b82811015620002ea57888601518255948401946001909101908401620002c9565b5085821015620003095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610b5980620003296000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a0712d6811610066578063a0712d6814610205578063a457c2d714610218578063a9059cbb1461022b578063dd62ed3e1461023e57600080fd5b806370a082311461019d57806379cc6790146101c65780637a1395aa146101d957806395d89b41146101fd57600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461017557806342966c681461018857600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610251565b60405161010f9190610967565b60405180910390f35b61012b6101263660046109d1565b6102e3565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b3660046109fb565b6102fd565b60055460405160ff909116815260200161010f565b61012b6101833660046109d1565b610321565b61019b610196366004610a37565b610343565b005b61013f6101ab366004610a50565b6001600160a01b031660009081526020819052604090205490565b61019b6101d43660046109d1565b610350565b61019b6101e7366004610a72565b6005805460ff191660ff92909216919091179055565b610102610369565b61019b610213366004610a37565b610378565b61012b6102263660046109d1565b610382565b61012b6102393660046109d1565b610402565b61013f61024c366004610a95565b610410565b60606003805461026090610ac8565b80601f016020809104026020016040519081016040528092919081815260200182805461028c90610ac8565b80156102d95780601f106102ae576101008083540402835291602001916102d9565b820191906000526020600020905b8154815290600101906020018083116102bc57829003601f168201915b5050505050905090565b6000336102f181858561043b565b60019150505b92915050565b60003361030b858285610560565b6103168585856105da565b506001949350505050565b6000336102f18185856103348383610410565b61033e9190610b02565b61043b565b61034d338261077e565b50565b61035b823383610560565b610365828261077e565b5050565b60606004805461026090610ac8565b61034d33826108a8565b600033816103908286610410565b9050838110156103f55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610316828686840361043b565b6000336102f18185856105da565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03831661049d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ec565b6001600160a01b0382166104fe5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ec565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061056c8484610410565b905060001981146105d457818110156105c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ec565b6105d4848484840361043b565b50505050565b6001600160a01b03831661063e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ec565b6001600160a01b0382166106a05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ec565b6001600160a01b038316600090815260208190526040902054818110156107185760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ec565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d4565b6001600160a01b0382166107de5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ec565b6001600160a01b038216600090815260208190526040902054818110156108525760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ec565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610553565b6001600160a01b0382166108fe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ec565b80600260008282546109109190610b02565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561099457858101830151858201604001528201610978565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146109cc57600080fd5b919050565b600080604083850312156109e457600080fd5b6109ed836109b5565b946020939093013593505050565b600080600060608486031215610a1057600080fd5b610a19846109b5565b9250610a27602085016109b5565b9150604084013590509250925092565b600060208284031215610a4957600080fd5b5035919050565b600060208284031215610a6257600080fd5b610a6b826109b5565b9392505050565b600060208284031215610a8457600080fd5b813560ff81168114610a6b57600080fd5b60008060408385031215610aa857600080fd5b610ab1836109b5565b9150610abf602084016109b5565b90509250929050565b600181811c90821680610adc57607f821691505b602082108103610afc57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102f757634e487b7160e01b600052601160045260246000fdfea2646970667358221220d2f4cd5b3214b4afcf457f0b23ef33b5ccce80a994abef63a11a1eb414ef810464736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a0712d6811610066578063a0712d6814610205578063a457c2d714610218578063a9059cbb1461022b578063dd62ed3e1461023e57600080fd5b806370a082311461019d57806379cc6790146101c65780637a1395aa146101d957806395d89b41146101fd57600080fd5b806323b872dd116100d357806323b872dd1461014d578063313ce56714610160578063395093511461017557806342966c681461018857600080fd5b806306fdde03146100fa578063095ea7b31461011857806318160ddd1461013b575b600080fd5b610102610251565b60405161010f9190610967565b60405180910390f35b61012b6101263660046109d1565b6102e3565b604051901515815260200161010f565b6002545b60405190815260200161010f565b61012b61015b3660046109fb565b6102fd565b60055460405160ff909116815260200161010f565b61012b6101833660046109d1565b610321565b61019b610196366004610a37565b610343565b005b61013f6101ab366004610a50565b6001600160a01b031660009081526020819052604090205490565b61019b6101d43660046109d1565b610350565b61019b6101e7366004610a72565b6005805460ff191660ff92909216919091179055565b610102610369565b61019b610213366004610a37565b610378565b61012b6102263660046109d1565b610382565b61012b6102393660046109d1565b610402565b61013f61024c366004610a95565b610410565b60606003805461026090610ac8565b80601f016020809104026020016040519081016040528092919081815260200182805461028c90610ac8565b80156102d95780601f106102ae576101008083540402835291602001916102d9565b820191906000526020600020905b8154815290600101906020018083116102bc57829003601f168201915b5050505050905090565b6000336102f181858561043b565b60019150505b92915050565b60003361030b858285610560565b6103168585856105da565b506001949350505050565b6000336102f18185856103348383610410565b61033e9190610b02565b61043b565b61034d338261077e565b50565b61035b823383610560565b610365828261077e565b5050565b60606004805461026090610ac8565b61034d33826108a8565b600033816103908286610410565b9050838110156103f55760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610316828686840361043b565b6000336102f18185856105da565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b03831661049d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103ec565b6001600160a01b0382166104fe5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103ec565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b600061056c8484610410565b905060001981146105d457818110156105c75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103ec565b6105d4848484840361043b565b50505050565b6001600160a01b03831661063e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103ec565b6001600160a01b0382166106a05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103ec565b6001600160a01b038316600090815260208190526040902054818110156107185760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103ec565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36105d4565b6001600160a01b0382166107de5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016103ec565b6001600160a01b038216600090815260208190526040902054818110156108525760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016103ec565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610553565b6001600160a01b0382166108fe5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103ec565b80600260008282546109109190610b02565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600060208083528351808285015260005b8181101561099457858101830151858201604001528201610978565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146109cc57600080fd5b919050565b600080604083850312156109e457600080fd5b6109ed836109b5565b946020939093013593505050565b600080600060608486031215610a1057600080fd5b610a19846109b5565b9250610a27602085016109b5565b9150604084013590509250925092565b600060208284031215610a4957600080fd5b5035919050565b600060208284031215610a6257600080fd5b610a6b826109b5565b9392505050565b600060208284031215610a8457600080fd5b813560ff81168114610a6b57600080fd5b60008060408385031215610aa857600080fd5b610ab1836109b5565b9150610abf602084016109b5565b90509250929050565b600181811c90821680610adc57607f821691505b602082108103610afc57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102f757634e487b7160e01b600052601160045260246000fdfea2646970667358221220d2f4cd5b3214b4afcf457f0b23ef33b5ccce80a994abef63a11a1eb414ef810464736f6c63430008120033", "devdoc": { "events": { "Approval(address,address,uint256)": { @@ -432,7 +436,7 @@ "notice": "Used in tests to test different decimals scenarios." } }, - "notice": "Used for testing purposes only. It represents: - a FIAT-based stablecoin when used to test the LToken contract, - the $LDY token when used to test the LDYStaking contract. This contract accept decimals as constructor argument, so it can be used to to easily test different decimals scenarios.", + "notice": "Used for testing purposes only, and used to generate ABIs for Wagmi contracts calls. It represents: - a FIAT-based stablecoin when used to test the LToken contract, - the $LDY token when used to test the LDYStaking contract. This contract accept decimals as constructor argument, so it can be used to to easily test different decimals scenarios.", "version": 1 }, "storageLayout": { @@ -478,7 +482,7 @@ "type": "t_string_storage" }, { - "astId": 10880, + "astId": 4758, "contract": "contracts/src/GenericERC20.sol:GenericERC20", "label": "_decimals", "offset": 0, @@ -523,4 +527,4 @@ } } } -} +} \ No newline at end of file diff --git a/contracts/hardhat/deployments/localhost/solcInputs/1c94255f5edec71501da736e9b19ae5f.json b/contracts/hardhat/deployments/localhost/solcInputs/1c94255f5edec71501da736e9b19ae5f.json new file mode 100644 index 00000000..63091b47 --- /dev/null +++ b/contracts/hardhat/deployments/localhost/solcInputs/1c94255f5edec71501da736e9b19ae5f.json @@ -0,0 +1,177 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeTo(address newImplementation) public virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../security/PausableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract unpausable.\n */\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\n function __ERC20Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../utils/SafeERC20Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the ERC20 token contract to support token wrapping.\n *\n * Users can deposit and withdraw \"underlying tokens\" and receive a matching number of \"wrapped tokens\". This is useful\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\n * wrapping of an existing \"basic\" ERC20 into a governance token.\n *\n * _Available since v4.2._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\n IERC20Upgradeable private _underlying;\n\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n __ERC20Wrapper_init_unchained(underlyingToken);\n }\n\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n require(underlyingToken != this, \"ERC20Wrapper: cannot self wrap\");\n _underlying = underlyingToken;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n */\n function decimals() public view virtual override returns (uint8) {\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\n return value;\n } catch {\n return super.decimals();\n }\n }\n\n /**\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\n */\n function underlying() public view returns (IERC20Upgradeable) {\n return _underlying;\n }\n\n /**\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\n */\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\n address sender = _msgSender();\n require(sender != address(this), \"ERC20Wrapper: wrapper can't deposit\");\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/src/abstracts/base/BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"../GlobalOwnableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"../GlobalRestrictableUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../RecoverableUpgradeable.sol\";\n\n/**\n * @title BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract acts as a base for numerous contracts in this codebase,\n * minimizing code repetition and enhancing readability and maintainability.\n *\n * @dev For further details, see \"Base\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract BaseUpgradeable is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n GlobalPausableUpgradeable,\n GlobalRestrictableUpgradeable,\n RecoverableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_\n ) internal onlyInitializing {\n __UUPSUpgradeable_init();\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n __Recoverable_init_unchained();\n }\n\n function __Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/base/ERC20BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport {ERC20PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"./BaseUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\n\n/**\n * @title ERC20BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract is an extension of BaseUpgradeable intended to be used\n * as a base for ERC20 tokens contracts.\n *\n * @dev For further details, see \"ERC20BaseUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract ERC20BaseUpgradeable is\n ERC20Upgradeable,\n BaseUpgradeable,\n ERC20PausableUpgradeable\n{\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param name_ The display name of the token.\n * @param symbol_ The symbol of the token.\n */\n function __ERC20Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n string memory name_,\n string memory symbol_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __ERC20_init(name_, symbol_);\n __ERC20Pausable_init_unchained();\n }\n\n function __ERC20Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\n * state from the GlobalPause contract.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, PausableUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\n * The ERC20PausableUpgradeable version is preferred because it also checks that\n * the contract is not paused before allowing the transfer.\n * @inheritdoc ERC20PausableUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n virtual\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\n whenNotPaused\n notBlacklisted(from)\n notBlacklisted(to)\n {\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalOwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {GlobalOwner} from \"../GlobalOwner.sol\";\n\n/**\n * @title GlobalOwnableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\n * contract (see GlobalOwner.sol). This design facilitates centralized management\n * of ownership for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalOwner state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalOwnableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\n /**\n * @notice The GlobalOwner contract the ownership will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalOwner private _globalOwner;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init_unchained(globalOwner_);\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\n // the initial _owner value, calling it would have no effect.\n }\n\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\n _globalOwner = GlobalOwner(globalOwner_);\n }\n\n /**\n * @notice Retrieves the address of GlobalOwner contract.\n * @return The address of the GlobalOwner contract.\n */\n function globalOwner() public view returns (address) {\n return address(_globalOwner);\n }\n\n /**\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\n * from the GlobalOwner contract instead.\n * @return The address of the owner\n */\n function owner() public view override returns (address) {\n return _globalOwner.owner();\n }\n\n /**\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function transferOwnership(address newOwner) public view override onlyOwner {\n newOwner; // Silence unused variable compiler warning\n revert(\"L8\");\n }\n\n /**\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function renounceOwnership() public view override onlyOwner {\n revert(\"L65\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalPausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalPause} from \"../GlobalPause.sol\";\n\n/**\n * @title GlobalPausableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a pause state from the specified GlobalPause\n * contract (see GlobalPause.sol). This design facilitates centralized management of\n * pause state for all the Ledgity Yield contracts.\n *\n * @dev Security measure\n * The _globalPause state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalPausableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\n /**\n * @notice The GlobalPause contract the pause state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalPause private _globalPause;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalPause_ The address of the GlobalPause contract.\n */\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n }\n\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\n _globalPause = GlobalPause(globalPause_);\n }\n\n /**\n * @notice Retrieves the address of GlobalPause contract.\n * @return The address of the GlobalPause contract.\n */\n function globalPause() public view returns (address) {\n return address(_globalPause);\n }\n\n /**\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\n * from the GlobalPause contract instead.\n * @return Whether the contract is paused or not.\n */\n function paused() public view virtual override returns (bool) {\n return _globalPause.paused();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalRestrictableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalBlacklist} from \"../GlobalBlacklist.sol\";\n\n/**\n * @title GlobalRestrictableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a blacklist state from the specified\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\n * centralized management of a blacklist for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalBlacklist state must be set at initialization time and, for evident\n * security reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalRestrictableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalRestrictableUpgradeable is Initializable {\n /**\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalBlacklist private _globalBlacklist;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n }\n\n function __GlobalRestrictable_init_unchained(\n address globalBlacklist_\n ) internal onlyInitializing {\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\n }\n\n /**\n * @notice Retrieves the address of GlobalBlacklist contract.\n * @return The address of the GlobalBlacklist contract.\n */\n function globalBlacklist() public view returns (address) {\n return address(_globalBlacklist);\n }\n\n /**\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n */\n modifier notBlacklisted(address account) {\n require(isBlacklisted(account) == false, \"L9\");\n _;\n }\n\n /**\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n * @return Whether the account is blacklisted.\n */\n function isBlacklisted(address account) internal view returns (bool) {\n return _globalBlacklist.isBlacklisted(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/InvestUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Contracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"./GlobalPausableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"./GlobalRestrictableUpgradeable.sol\";\nimport \"./base/BaseUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../abstracts/RecoverableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {APRHistory as APRH} from \"../libs/APRHistory.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title InvestUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with utilities to manage an invested token,\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\n *\n * @dev Intuition:\n * This contract primarily exists for code splitting and reusability. It unburdens the\n * LToken contract code, making it easier to understand and maintain.\n *\n * This contract is generic because it may be used in the LDYStaking contract in the future.\n *\n * @dev Definitions:\n * - Investment: The act of depositing or investing tokens into the contract.\n * - Investment period: Time between the last invested amount change and the present.\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\n * distributed between investment periods.\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\n *\n * @dev Derived contract must:\n * - Set invested token during initialization\n * - Implement _investmentOf() function\n * - (optionally) Implement _distributeRewards() function\n *\n * @dev For further details, see \"InvestmentUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract InvestUpgradeable is BaseUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using APRH for APRH.Pack[];\n\n /**\n * @notice Represents an account's investment period.\n * @param timestamp The timestamp of the most recent rewards distribution.\n * @param ref The reference of the last APR checkpoint at that timestamp.\n */\n struct InvestmentPeriod {\n uint40 timestamp; // Supports dates up to 20/02/36812\n APRH.Reference ref;\n }\n\n /**\n * @notice Represents the investment details of an account.\n * @param period The current investment period of the account.\n * @param virtualBalance May hold a part of account rewards until they are claimed.\n */\n struct AccountDetails {\n InvestmentPeriod period;\n uint256 virtualBalance;\n }\n\n /// @notice Holds a reference to the invested token's contract.\n IERC20Upgradeable private _invested;\n\n /// @notice Holds investment details of each account.\n mapping(address => AccountDetails) internal accountsDetails;\n\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\n APRH.Pack[] private _aprHistory;\n\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\n mapping(address => address) public rewardsRedirectsFromTo;\n mapping(address => address[]) public rewardsRedirectsToFrom;\n\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\n bool private _isClaiming;\n\n /**\n * @notice Emitted to inform listeners about a change in the APR's value.\n * @param newAPRUD7x3 The new APR in UD7x3 format.\n */\n event APRChangeEvent(uint16 newAPRUD7x3);\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param invested_ The address of the invested token contract.\n */\n function __Invest_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address invested_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __Invest_init_unchained(invested_);\n }\n\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\n // Set invested token\n _invested = IERC20Upgradeable(invested_);\n\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\n // of an empty APR history\n _aprHistory.setAPR(0);\n }\n\n /**\n * @notice Retrieves the reference to the invested token contract.\n * @return The reference to the invested token contract.\n */\n function invested() public view returns (IERC20Upgradeable) {\n return _invested;\n }\n\n /**\n * @notice Updates the investment APR. Restricted to owner.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(uint16 aprUD7x3) public onlyOwner {\n _aprHistory.setAPR(aprUD7x3);\n emit APRChangeEvent(aprUD7x3);\n }\n\n /**\n * @notice Retrieves the most recently set APR.\n * @return The current APR in UD7x3 format.\n */\n function getAPR() public view returns (uint16) {\n return _aprHistory.getAPR();\n }\n\n /**\n * @notice Enables redirection of rewards from one account to another.\n * @param from The address of the account to redirect rewards from.\n * @param to The address of the account to redirect rewards to.\n */\n function startRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure the address is not already redirecting rewards\n require(rewardsRedirectsFromTo[from] == address(0), \"L62\");\n\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L12\");\n require(to != address(0), \"L13\");\n\n // Ensure 'from' and 'to' addresses are distinct\n require(from != to, \"L14\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L15\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Activate rewards redirection\n rewardsRedirectsFromTo[from] = to;\n rewardsRedirectsToFrom[to].push(from);\n }\n\n /**\n * @notice Disable an active rewards redirection.\n * @param from The address of the account to stop redirecting rewards from.\n * @param to The address of the account to stop redirecting rewards to.\n */\n function stopRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L16\");\n require(to != address(0), \"L17\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L18\");\n\n // Ensure a rewards redirection was active\n require(rewardsRedirectsFromTo[from] == to, \"L19\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Retrieve 'from' index in the redirection array of 'to'\n int256 fromIndex = -1;\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\n if (rewardsRedirectsToFrom[to][i] == from) {\n fromIndex = int256(i);\n break;\n }\n }\n\n // fromIndex should never be -1 at this point\n assert(fromIndex >= 0);\n\n // Deactivate rewards redirection\n rewardsRedirectsFromTo[from] = address(0);\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\n rewardsRedirectsToFrom[to].length - 1\n ];\n rewardsRedirectsToFrom[to].pop();\n }\n\n /**\n * @notice Retrieves the total amount of tokens invested by the given account.\n * @dev Derived contracts must implement this function.\n * @param account The account to get the investment of.\n * @return The total amount of tokens invested by the given account.\n */\n function _investmentOf(address account) internal view virtual returns (uint256);\n\n /**\n * @notice Distributes a specified amount of rewards to a given account.\n * @dev Derived contracts may optionally implement this function.\n * @dev Implementations must return true to indicate a successful distribution, and\n * false otherwise. If it returns false, the rewards will be added to the account's\n * virtual balance, in order to be claimed later.\n * @param account The account to claim the rewards of.\n * @param amount The amount of rewards to claim.\n * @return Whether the rewards distribution was successfull.\n */\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\n account; // Silence unused variables warning\n amount;\n return false;\n }\n\n /**\n * @notice Computes the rewards accrued over a specified period of time, based on a\n * given APR and amount of invested tokens.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param beginTimestamp The moment the period commenced.\n * @param endTimestamp The moment the period concluded.\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\n * @param investedAmount The amount of tokens deposited/invested during the period.\n * @return The amount of rewards generated during the period.\n */\n function _calculatePeriodRewards(\n uint40 beginTimestamp,\n uint40 endTimestamp,\n uint16 aprUD7x3,\n uint256 investedAmount\n ) internal view returns (uint256) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Compute the number of elapsed years\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\n\n // Compute the growth in invested amount (thanks to rewards)\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\n\n // Compute and return the rewards\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(rewardsSUD, d);\n }\n\n /**\n * @notice Computes the sum of given account's invested amount, plus invested amount\n * of all accounts that recursively redirect rewards to this account.\n * @param account The account to calculate the deep investment of.\n * @return deepInvestedAmount The deep invested amount.\n */\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\n // Consider account's direct investment\n deepInvestedAmount += _investmentOf(account);\n\n // But also the deep investments of all accounts redirecting rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param account The account to calculate the unclaimed rewards of.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\n */\n function _rewardsOf(\n address account,\n bool autocompound\n ) internal view returns (uint256 rewards) {\n // Retrieve account's investment details\n AccountDetails memory details = accountsDetails[account];\n\n // Retrieve account's deep invested amount\n uint256 investedAmount = _deepInvestmentOf(account);\n\n // Return 0 if the account has never invested or has no invested amount\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\n\n // Retrieve reference and data of APR checkpoint at which started investment period\n APRH.Reference memory currRef = details.period.ref;\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\n\n // Retrieve reference of latest APR checkpoint\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\n\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\n // See \"InvestUpgradeable > Yield calculation > 1)\" section of the whitepaper\n rewards = details.virtualBalance;\n\n // If start checkpoint is not the latest one\n if (!APRH.eq(currRef, latestRef)) {\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // 2) Calculate rewards from investment period start to next checkpoint\n // See \"InvestUpgradeable > Yield calculation > 2)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n\n // 3) Calculate rewards for each crossed pair of checkpoints\n // See \"InvestUpgradeable > Yield calculation > 3)\" section of the whitepaper\n while (true) {\n // Set next checkpoint as the current one\n currRef = nextRef;\n currCheckpoint = nextCheckpoint;\n\n // Break if current checkpoint is the latest one\n if (APRH.eq(currRef, latestRef)) break;\n\n // Else, retrieve the new next checkpoint\n nextRef = APRH.incrementReference(currRef);\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // Calculate rewards between the current pair of checkpoints\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n\n // 4) Calculate rewards from the latest checkpoint to now\n // See \"InvestUpgradeable > Yield calculation > 4)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n } else {\n // 2.bis) Calculate rewards from investment period start to now\n // See \"InvestUpgradeable > Yield calculation > 2.bis)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n }\n\n /**\n * @notice Recursively resets the investment period of the specified account and of\n * all accounts that directly or indirectly redirect rewards to this account.\n * @param account The account to deeply reset the investment period of.\n */\n function _deepResetInvestmentPeriodOf(address account) internal {\n // Reset account investment period timestamp and APR checkpoint to latest ones\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\n\n // Also reset the ones of all accounts that recursively redirect rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Hook to be invoked before the invested amount of an account changes. It\n * ensures that rewards are distributed and that account's investment period is reset.\n * @param account The account whose invested amount is going to change.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n */\n function _beforeInvestmentChange(address account, bool autocompound) internal {\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\n // minted in LToken._distributeRewards(), this guards against infinite loop.\n if (_isClaiming) return;\n\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\n // As first call will treat both addresses, the second call would be redundant.\n // Therefore, we skip accounts already processed in this block to save up some gas.\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\n\n // If account redirects its rewards\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\n if (redirectRewardsTo != address(0)) {\n // Call hook on redirection target (this will indirectly reset the investment\n // of this source account) and return\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\n return;\n }\n\n // Else, compute account's undistributed/unclaimed rewards\n uint256 rewards = _rewardsOf(account, autocompound);\n\n // If there are some rewards\n if (rewards > 0) {\n // Try to distribute rewards to account\n _isClaiming = true;\n bool distributed = _distributeRewards(account, rewards);\n _isClaiming = false;\n\n // If rewards have not been distributed, accumulate them in account's virtual balance\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\n }\n\n // Finally, deeply reset investment period of the account\n _deepResetInvestmentPeriodOf(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/RecoverableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Conracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title RecoverableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with helper functions allowing the recovery of\n * assets accidentally sent to them.\n *\n * @dev Where are utilities Ether, ERC721, etc.?\n * This abstract contract currently supports only ERC20 tokens. Derived contracts\n * in this codebase currently do not implement the necessary functions to receive Ether\n * or ERC721/ERC1155 tokens, so no recovery functions are provided for these assets.\n *\n * @dev For further details, see \"RecoverableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init(globalOwner_);\n __Recoverable_init_unchained();\n }\n\n function __Recoverable_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Recovers a specified amount of a given token address. Will fail if the\n * contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\n // Ensure the specified amount is not zero\n require(amount > 0, \"L10\");\n\n // Create a reference to token's contract\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\n\n // Ensure there is enough token to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L11\");\n\n // Transfer the recovered token amount to the sender\n tokenContract.safeTransfer(_msgSender(), amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/DummyLDYStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title LDYStaking\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This contract acts as a placeholder for the real LDYStaking contract until\n * this one is deployed.\n *\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\n * one the LToken contract relies on.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LDYStaking is Ownable2Step {\n /**\n * @notice Holds a mapping of addresses that default to the highest staking tier.\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\n */\n mapping(address => bool) public highTierAccounts;\n\n /**\n * @notice Update high tier status of a given account.\n * @param account The account to update the high tier status of.\n */\n function setHighTierAccount(address account, bool status) public onlyOwner {\n highTierAccounts[account] = status;\n }\n\n /**\n * @dev Dummy tierOf() function that always return that the given account is not\n * elligible to any LDY staking tier, except if the account is in the\n * highTierAccounts mapping.\n * @param account The account to check the tier of.\n */\n function tierOf(address account) public view returns (uint256 tier) {\n if (highTierAccounts[account]) return 3;\n return 0;\n }\n}\n" + }, + "contracts/src/GenericERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n/**\n * @notice Used for testing purposes only, and used to generate ABIs for Wagmi contracts calls.\n * It represents:\n * - a FIAT-based stablecoin when used to test the LToken contract,\n * - the $LDY token when used to test the LDYStaking contract.\n * This contract accept decimals as constructor argument, so it can be used to to\n * easily test different decimals scenarios.\n */\ncontract GenericERC20 is ERC20, ERC20Burnable {\n uint8 private _decimals;\n\n constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) {\n _decimals = decimals_;\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n\n /**\n * Used in tests to test different decimals scenarios.\n */\n function setDecimals(uint8 decimals_) public {\n _decimals = decimals_;\n }\n}\n" + }, + "contracts/src/GlobalBlacklist.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalBlacklist\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global mapping of blacklisted accounts shared by all contracts of the\n * Ledgity Yield codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\n * and getter functions to easily check against this global blacklist.\n *\n * @dev For further details, see \"GlobalBlacklist\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Mapping of accounts to their blacklist status.\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\n */\n mapping(address => bool) private _list;\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Adds a given account to the blacklist.\n * @param account The account's address to be blacklisted.\n */\n function blacklist(address account) external onlyOwner {\n require(account != address(0), \"L20\");\n _list[account] = true;\n }\n\n /**\n * @notice Removes a given account from the blacklist.\n * @param account The account's address to be un-blacklisted.\n */\n function unBlacklist(address account) external onlyOwner {\n _list[account] = false;\n }\n\n /**\n * @notice Checks whether a given account is blacklisted.\n * @param account Address of the account to check.\n * @return 'true' if the account is blacklisted, 'false' otherwise\n */\n function isBlacklisted(address account) external view returns (bool) {\n // Gas optimization: Avoid accessing storage if account is the zero address\n // (e.g, during a mint or a burn of tokens)\n if (account == address(0)) return false;\n\n // Else, return current account's blacklist status\n return _list[account];\n }\n}\n" + }, + "contracts/src/GlobalOwner.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\n/**\n * @title GlobalOwner\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds the address of a global owner account shared by all contracts of the\n * Ledgity Yield's codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\n * owner() function that retrieves the owner's address from this contract instead.\n *\n * @dev For further details, see \"GlobalOwner\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize() public initializer {\n __Ownable2Step_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n}\n" + }, + "contracts/src/GlobalPause.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalPause\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global pause state shared by all contracts of the Ledgity Yield\n * codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\n * paused() function that retrieves the pause state from this contract instead.\n *\n * @dev For further details, see \"GlobalPause\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalPause is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n PausableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\n * but restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n}\n" + }, + "contracts/src/interfaces/ITransfersListener.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ITransfersListener {\n function onLTokenTransfer(address from, address to, uint256 amount) external;\n}\n" + }, + "contracts/src/libs/APRHistory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/**\n * @title APRHistory\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This library offers utilities to efficiently maintain the history of an\n * on-chain APR (Annual Percentage Rate) state. Each entry in this history is called\n * a \"checkpoint\".\n *\n * @dev Intuition:\n * Each checkpoint in an APR history consists of two data:\n * - the creation timestamp\n * - the APR at that time\n *\n * Given that reading and writing to storage slots are among the most costly operations\n * in Solidity, this library provides a way to store those data in a way that minimizes\n * the number of used storage slots.\n *\n * Instead of storing each checkpoint in a separate storage slot, this library\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\n *\n * @dev Definitions:\n * - Checkpoint: A record of an APR change\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\n * - History: A dynamic array of packs\n * - Reference: A storage pointer to a checkpoint in the APR history\n * - CheckpointData: An in-memory representation of a checkpoint data\n *\n * @dev Value limitation:\n * This library can accommodate APRs only up to 65.536%. This is however sufficient for\n * APR in LToken contract, which is expected to remain below 10%.\n *\n * @dev For further details, see \"APRHistory\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary APRHistory {\n /**\n * @notice Represents data of a checkpoint extracted from the on-chain history.\n * For on-chain representation see \"Pack\" struct.\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\n * @param timestamp Timestamp of the checkpoint's creation.\n */\n struct CheckpointData {\n uint16 aprUD7x3; // Allows up to 65.536%\n uint40 timestamp; // Supports dates up to 20/02/36812\n }\n\n /**\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\n * @param aprsUD7x3 Array of checkpoints' APRs.\n * @param timestamps Array of checkpoints' timestamps.\n * @param cursor Index of the next checkpoint to be written.\n */\n struct Pack {\n uint16[4] aprsUD7x3;\n uint40[4] timestamps;\n uint32 cursor;\n }\n\n /**\n * @notice Represents a storage pointer to a specific checkpoint in the history.\n * @param packIndex Index of the pack the checkpoint belongs to.\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\n */\n struct Reference {\n uint256 packIndex;\n uint32 cursorIndex;\n }\n\n /**\n * @notice Compares two checkpoints references.\n * @param ref1 The first reference to compare.\n * @param ref2 The second reference to compare.\n * @return Whether the two references points to the same checkpoint.\n */\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\n }\n\n /**\n * @notice Returns the reference of the checkpoint that should come right after the\n * referenced checkpoint in the APR history.\n * @param ref The reference to be incremented.\n * @return The incremented reference.\n */\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L1\");\n\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\n //\n // Else, return ref of next slot in current pack\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\n }\n\n /**\n * @notice Extracts checkpoint data from a given reference and in APR history.\n * @param self The APR history to extract the checkpoint from.\n * @param ref The reference of the checkpoint data to extract.\n * @return The extracted checkpoint's data.\n */\n function getDataFromReference(\n Pack[] storage self,\n Reference memory ref\n ) public view returns (CheckpointData memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L2\");\n\n // Ensure pack index of the given ref exists in history\n require(ref.packIndex < self.length, \"L3\");\n\n // Retrieve pack data from history\n Pack memory pack = self[ref.packIndex];\n\n // Ensure cursor index of the given ref has been written\n require(ref.cursorIndex < pack.cursor, \"L4\");\n\n // Build and return the checkpoint data\n return\n CheckpointData({\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\n timestamp: pack.timestamps[ref.cursorIndex]\n });\n }\n\n /**\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\n * @param self The history to extract the reference from.\n * @return The reference of the latest checkpoint.\n */\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\n // Ensure the given history is not empty\n require(self.length != 0, \"L5\");\n\n // Retrieve latest pack's index and cursor\n uint256 packIndex = self.length - 1;\n uint32 packCursor = self[packIndex].cursor;\n\n // If this is the first pack ever, ensure it is not empty\n if (packIndex == 0) require(packCursor != 0, \"L6\");\n\n // If the pack is empty, return ref of previous pack's latest slot\n if (packCursor == 0) return Reference(packIndex - 1, 3);\n //\n // Else, return ref of previous slot in current pack\n else return Reference(packIndex, packCursor - 1);\n }\n\n /**\n * @notice Appends a new empty pack to the end of the given APR history array.\n * @param self The APR history to append an empty to.\n */\n function newBlankPack(Pack[] storage self) internal {\n // If history is not empty, ensure the latest pack is full\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \"L7\");\n\n // Push a new blank pack to the history array\n self.push(\n Pack({\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\n cursor: 0\n })\n );\n }\n\n /**\n * @notice Write a new APR checkpoint at the end of the given history array.\n * @param self The array of packs to write the new checkpoint to.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\n // Determine the reference where the new checkpoint should be written\n Reference memory newRef = self.length == 0\n ? Reference(0, 0)\n : incrementReference(getLatestReference(self));\n\n // If pack to be written doesn't exist yet, push a new blank pack in history\n if (newRef.packIndex >= self.length) newBlankPack(self);\n\n // Retrieve the pack where the new checkpoint will be stored\n Pack memory pack = self[newRef.packIndex];\n\n // Add new checkpoint's data to the pack\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\n\n // Increment the pack's cursor\n pack.cursor++;\n\n // Write the updated pack in storage\n self[newRef.packIndex] = pack;\n }\n\n /**\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\n * @param self The history array to read APR from.\n * @return The latest checkpoint's APR.\n */\n function getAPR(Pack[] storage self) public view returns (uint16) {\n // Retrieve the latest checkpoint data\n Reference memory ref = getLatestReference(self);\n CheckpointData memory data = getDataFromReference(self, ref);\n\n // Return the latest checkpoint's APR\n return data.aprUD7x3;\n }\n}\n" + }, + "contracts/src/libs/SUD.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title SUD\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice SUD serves as an intermediary number format for calculations within this\n * codebase. It ensures consistency and reduces precision losses. This library\n * facilitates conversions between various number formats and the SUD format.\n *\n * @dev Intuition:\n * This codebase employs the UD (unsigned decimal fixed-point numbers) format to\n * represent both percentage rates and tokens amounts.\n *\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\n * the decimals() value of the involved tokens.\n *\n * Three challenges arise from this:\n * 1) To compute values together, it's essential that they are in the same format\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\n * precision loss (because division shrinks). A common approach is to scale up and\n * down values by a few decimals before and after performing calculations.\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\n * be shrunk in case token's decimals number is in [0, 2].\n *\n * To address these challenges, this library provides the SUD format, which acts as a\n * consistent and scaled intermediate format to perform calculations.\n *\n * SUD is an acronym for either \"Scaled UD\" or \"Safe UD\".\n *\n * @dev Definitions:\n * - Integer: A number without fractional part, e.g., block.timestamp\n * - UD: A decimal unsigned fixed-point number. The \"UD\" notation is inspired from\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\n * - Amount: A token amount. A UD with an unknown repartition of digits between integral\n * and fractional parts (as token amounts have variable decimal numbers)\n * - Rate: A percentage rate. An UD with 7 integral digits and 3 fractional ones (= UD7x3)\n * - SUD: An intermediate format to perform calculations involving Rates and Amounts. A UD\n * with 3 more decimals than the involved UD with the highest decimals number. As\n * rates are represented by UD7x3, a SUD number has at least 6 decimals (3+3) and\n * so ranges from UD71x6 to UD0x77 formats.\n *\n * @dev A conversion library:\n * This library provides utilities to perform the following conversions:\n * - Amount <--> SUD\n * - Rate (UD7x3) <--> SUD\n * - Integer <--> SUD\n *\n * @dev Why scaling by 3 decimals?\n * - It provides an adequate degree of precision for this codebase,\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\n * the involved token's decimal number, so is gas efficient.\n *\n * @dev Why internal functions?\n * The functions of this library are not set to external because incorporating them\n * directly into contracts is more gas-efficient. Given their minimal size and frequent\n * usage in the InvestUpgradeable, LDYStaking, and LToken contracts, any bytecode savings\n * from making them external are negated by the additional bytecode required for external\n * calls to this library. This can be observed by comparing the output of `bun cc:size`\n * when those functions's visibility is set to external or internal.\n *\n * @dev Precision warning:\n * While this library mitigates precision loss during calculations on UD numbers, it's\n * important to note that tokens with lower decimal counts and supply inherently suffer\n * more from precision loss. Conversely, tokens with higher decimal counts and supply\n * will experience less precision loss.\n *\n * @dev For further details, see \"SUD\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary SUD {\n /**\n * @notice Retrieves decimals number of the given ERC20 contract address.\n * @param tokenAddress The address to retrieve decimals number from.\n * @return decimals The decimals number of the given ERC20 contract address.\n */\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\n }\n\n /**\n * @notice Convert a given token amount into SUD format.\n * @param nAmount The token amount to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The amount in SUD format\n */\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\n\n // Else return a number with decimals+3 fractional digits\n return nAmount * 10 ** 3;\n }\n\n /**\n * @notice Convert a given SUD number into token amount format.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nAmount The number in amount format\n */\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** 3;\n }\n\n /**\n * @notice Converts a given UD7x3 rate into SUD format.\n * @param nUD7x3 The UD7x3 rate to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The rate in SUD format.\n */\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nUD7x3 * 10 ** 3;\n\n // Else, return a number with decimals+3 fractional digits\n return nUD7x3 * 10 ** decimals;\n }\n\n /**\n * @notice Converts a given SUD number into a UD7x3 rate.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nUD7x3 The number in UD7x3 rate format.\n */\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 3;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** decimals;\n }\n\n /**\n * @notice Converts a given integer into SUD format.\n * @param n The integer to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The integer in SUD format.\n */\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return n * 10 ** 6;\n\n // Else, return a number with decimals+3 fractional digits\n return n * 10 ** (decimals + 3);\n }\n\n /**\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return n The SUD number as an integer.\n */\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 6;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** (decimals + 3);\n }\n}\n" + }, + "contracts/src/LToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Contracts\nimport {ERC20WrapperUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\";\nimport \"./abstracts/base/ERC20BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"./abstracts/InvestUpgradeable.sol\";\nimport {LDYStaking} from \"./DummyLDYStaking.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {SUD} from \"./libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport {ITransfersListener} from \"./interfaces/ITransfersListener.sol\";\n\n/**\n * @title LToken\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e.,\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\n * the form of additional L-Tokens, which are auto-compounded over time.\n *\n * @dev Definitions:\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\n * - Instant: Processed immediately.\n * - Request: Queued for later processing.\n * - Big Request: A requested withdrawal exceeding half of the retention rate.\n * - (Withdrawal) queue: A list of all requested withdrawals sorted by priority.\n * - Request ID: The index of a withdrawal request in the queue array.\n * - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain.\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\n * expected ways and are so considered safe to use by the contract.\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\n * processing.\n *\n * Note that words between parenthesis are sometimes omitted for brevity.\n *\n * @dev Deployment notice:\n * This contract can safely receive funds immediately after initialization. (i.e., there\n * is no way for funds to be sent to non-owned addresses). It is, however, recommended to\n * replace ASAP owner and fund wallets with multi-sig wallets.\n *\n * @dev For further details, see \"LToken\" section of whitepaper.\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n * @custom:security-contact security@ledgity.com\n */\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @dev Represents type of actions triggering ActivityEvent events.\n enum Action {\n Deposit,\n Withdraw\n }\n\n /// @dev Represents different status of actions triggering ActivityEvent events.\n enum Status {\n Queued,\n Cancelled,\n Success,\n Moved\n }\n\n /**\n * @notice Represents a withdrawal request in the queue.\n * @dev A request fits in a single storage slot (32 bytes).\n * @param account The account that initiated the request.\n * @param amount The amount of underlying tokens requested.\n */\n struct WithdrawalRequest {\n address account; // 20 bytes\n uint96 amount; // 12 bytes\n }\n\n /// @notice Upper limit of retention rate.\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\n\n /// @notice Upper limit of fees rate.\n uint32 private constant MAX_FEES_RATE_UD7x3 = 20 * 10 ** 3; // 20%\n\n /// @notice Used in activity events to represent the absence of request ID.\n int256 private constant NO_ID = -1;\n\n /// @notice Holds a reference to the LDYStaking contract.\n LDYStaking public ldyStaking;\n\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\n address payable public withdrawer;\n\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\n address public fund;\n\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\n uint32 public feesRateUD7x3;\n\n /// @notice Holds the retention rate in UD7x3 format.\n uint32 public retentionRateUD7x3;\n\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\n uint256 public unclaimedFees;\n\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\n uint256 public totalQueued;\n\n /**\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\n */\n uint256 public usableUnderlyings;\n\n /// @notice Holds an ordered list of active withdrawal requests.\n WithdrawalRequest[] public withdrawalQueue;\n\n /// @notice Holds the index of the next withdrawal request to process in the queue.\n uint256 public withdrawalQueueCursor;\n\n /**\n * @notice Holds a list of all currently frozen withdrawal requests.\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\n * it from blocking the queue.\n */\n WithdrawalRequest[] public frozenRequests;\n\n /**\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\n */\n ITransfersListener[] public transfersListeners;\n\n /**\n * @notice Emitted to inform listeners about a change in the contract's TVL.\n * @dev TVL = realTotalSupply()\n * @param newTVL The new TVL of the contract.\n */\n event TVLChangeEvent(uint256 newTVL);\n\n /**\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\n * @param account The account involved in the activity.\n * @param action The type of activity.\n * @param amount The amount of underlying tokens involved in the activity.\n * @param newStatus The new status of the activity.\n * @param newId The new ID of the request if it has been moved in the queue.\n */\n event ActivityEvent(\n int256 indexed id,\n address indexed account,\n Action indexed action,\n uint256 amount,\n uint256 amountAfterFees,\n Status newStatus,\n int256 newId\n );\n\n /**\n * @notice Emitted to inform listeners that some rewards have been minted.\n * @param account The account that received the rewards.\n * @param balanceBefore The balance of the account before the minting.\n * @param rewards The amount of minted rewards.\n */\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\n\n /// @notice Reverts if the function caller is not the withdrawer wallet.\n modifier onlyWithdrawer() {\n require(_msgSender() == withdrawer, \"L39\");\n _;\n }\n\n /// @notice Reverts if the function caller is not the fund wallet.\n modifier onlyFund() {\n require(_msgSender() == fund, \"L40\");\n _;\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyStaking_,\n address underlyingToken\n ) public initializer {\n // Initialize ERC20 base.\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\n __ERC20Base_init(\n globalOwner_,\n globalPause_,\n globalBlacklist_,\n string(abi.encodePacked(\"Ledgity \", underlyingSymbol)),\n string(abi.encodePacked(\"L\", underlyingSymbol))\n );\n\n // IMPORTANT: Below calls must not be restricted to owner at any point.\n // This is because the GlobalOwner contract may not be a fresh one, and so\n // the contract deployer may not be the owner anymore after ERC20Base init.\n\n // Initialize other parents contracts.\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\n __Invest_init_unchained(address(this));\n\n // Set LDYStaking contract\n ldyStaking = LDYStaking(ldyStaking_);\n\n // Set initial withdrawal fees rate to 0.3%\n feesRateUD7x3 = 300;\n\n // Set initial retention rate to 10%\n retentionRateUD7x3 = 10_000;\n\n // Default withdrawer and fund wallet to contract owner address. This prevents\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\n withdrawer = payable(owner());\n fund = payable(owner());\n }\n\n /**\n * @notice Required override of decimals() which is implemented by both\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\n * decimals amount of the underlying stablecoin token.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function decimals()\n public\n view\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\n returns (uint8)\n {\n return ERC20WrapperUpgradeable.decimals();\n }\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @notice Updates the current withdrawal fee rate.\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\n */\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\n require(feesRateUD7x3_ <= MAX_FEES_RATE_UD7x3, \"L88\");\n feesRateUD7x3 = feesRateUD7x3_;\n }\n\n /**\n * @notice Updates the current underlying token retention rate.\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\n * deposited assets will ever be exposed in this contract (reduces attack surface).\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\n */\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \"L41\");\n retentionRateUD7x3 = retentionRateUD7x3_;\n }\n\n /**\n * @notice Updates the address of LDYStaking contract.\n * @param ldyStakingAddress The address of the new LDYStaking contract.\n */\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\n require(ldyStakingAddress != address(0), \"L89\");\n ldyStaking = LDYStaking(ldyStakingAddress);\n }\n\n /**\n * @notice Updates the address of the withdrawer wallet.\n * @param withdrawer_ The address of the new withdrawer wallet.\n */\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\n // Ensure address is not the zero address (pre-processing fees would be lost else)\n require(withdrawer_ != address(0), \"L63\");\n\n // Set new withdrawer wallet's address\n withdrawer = withdrawer_;\n }\n\n /**\n * @notice Updates the address of the fund wallet.\n * @param fund_ The address of the new fund wallet.\n */\n function setFund(address payable fund_) public onlyOwner {\n // Ensure address is not the zero address (deposited tokens would be lost else)\n require(fund_ != address(0), \"L64\");\n\n // Set new fund wallet's address\n fund = fund_;\n }\n\n /**\n * @notice Adds a new contract to the L-Token transfers list.\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\n * specified contract will be called.\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\n * contracts that are not owned by the Ledgity team.\n * @param listenerContract The address of the new transfers listener contract.\n */\n function listenToTransfers(address listenerContract) public onlyOwner {\n require(listenerContract != address(0), \"L90\");\n transfersListeners.push(ITransfersListener(listenerContract));\n }\n\n /**\n * @notice Removes a contract from the L-Token transfers list.\n * @dev The onLTokenTransfer() function of the specified contract will not be called\n * anymore each time a L-Token transfer occurs.\n * @param listenerContract The address of the listener contract.\n */\n function unlistenToTransfers(address listenerContract) public onlyOwner {\n // Find index of listener contract in transferListeners array\n int256 index = -1;\n uint256 transfersListenersLength = transfersListeners.length;\n for (uint256 i = 0; i < transfersListenersLength; i++) {\n if (address(transfersListeners[i]) == listenerContract) {\n index = int256(i);\n break;\n }\n }\n\n // Revert if given contract wasn't listening to transfers\n require(index > -1, \"L42\");\n\n // Else, remove transfers listener contract from listeners array\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\n transfersListeners.pop();\n }\n\n /**\n * @notice Retrieves the amount of given account's not yet minted rewards.\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\n * context of LToken, this function returns the amount of rewards that have not been\n * distributed/minted yet to the specified account.\n * @dev This is particularly useful for off-chain services to display charts and\n * statistics, as seen in the Ledgity Yield's frontend.\n * @param account The account to check the unminted rewards of.\n * @return The amount of account's unminted rewards.\n */\n function unmintedRewardsOf(address account) public view returns (uint256) {\n return _rewardsOf(account, true);\n }\n\n /**\n * @notice Retrieves the \"real\" balance of an account, i.e., excluding its not yet\n * minted/distributed rewards.\n * @param account The account to check the real balance of.\n * @return The real balance of the account.\n */\n function realBalanceOf(address account) public view returns (uint256) {\n return super.balanceOf(account);\n }\n\n /**\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\n * not been yet minted to the specified account.\n * @param account The account to check the total balance of.\n * @return The total balance of the account.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return realBalanceOf(account) + unmintedRewardsOf(account);\n }\n\n /**\n * @notice Returns the \"real\" amount of existing L-Tokens, i.e., excluding not yet\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\n * @return The real total supply of L-Tokens.\n */\n function realTotalSupply() public view returns (uint256) {\n return super.totalSupply();\n }\n\n /**\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\n * fees and L-Tokens currently in the withdrawal queue.\n * @return The total supply of L-Tokens.\n */\n function totalSupply() public view override returns (uint256) {\n return realTotalSupply() + totalQueued + unclaimedFees;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address.\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\n * token from being the underlying token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the underlying token\n require(tokenAddress != address(underlying()), \"L43\");\n\n // Proceed to recovery\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @notice Recovers underlying tokens accidentally sent to the contract.\n * @dev To prevent owner from being able to drain the contract, this function only\n * allows recovering \"unusable\" underlying tokens, i.e., tokens that have not been\n * sent through fund() or deposit() functions.\n */\n function recoverUnderlying() external onlyOwner {\n // Compute the recoverable amount by taking the difference between the contract's\n // balance and the amount of usable underlying tokens\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\n\n // Revert if there is nothing to recover\n require(recoverableAmount > 0, \"L44\");\n\n // Else, proceed to underlying tokens recovery\n super.recoverERC20(address(underlying()), recoverableAmount);\n }\n\n /**\n * @notice Retrieves the amount of underlying tokens invested by the given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\n * LToken contract, the investment of an account is equal to its real balance.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return realBalanceOf(account);\n }\n\n /**\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract so\n * it can distribute rewards to accounts before each period reset.\n * @dev InvestUpgradeable contract already ensure that amount > 0.\n * @inheritdoc InvestUpgradeable\n */\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\n // Inform listeners of the rewards minting\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\n\n // Mint L-Tokens rewards to account\n _mint(account, amount);\n\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\n return true;\n }\n\n /**\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\n * called each time an account's balance is going to change.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\n * @inheritdoc ERC20BaseUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\n\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\n if (from != address(0)) _beforeInvestmentChange(from, true);\n if (to != address(0)) _beforeInvestmentChange(to, true);\n }\n\n /**\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\n * transfers listeners.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already checked in _beforeTokenTransfer().\n * @inheritdoc ERC20Upgradeable\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\n super._afterTokenTransfer(from, to, amount);\n\n // If some L-Token have been burned/minted, inform listeners of a TVL change\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\n\n // Trigger onLTokenTransfer() functions of all the transfers listeners\n for (uint256 i = 0; i < transfersListeners.length; i++) {\n transfersListeners[i].onLTokenTransfer(from, to, amount);\n }\n }\n\n /**\n * @notice Computes the maximum amount of underlying tokens that should be retained\n * by the contract (based on retention rate).\n * @return amount The expected amount of retained underlying tokens.\n */\n function getExpectedRetained() public view returns (uint256 amount) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert totalSupply and retentionRate to SUD\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\n\n // Compute and return expected retained amount\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(expectedRetainedSUD, d);\n }\n\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\n function _transferExceedingToFund() internal {\n // Retrieve the expected amount retained\n uint256 expectedRetained = getExpectedRetained();\n\n // If usable underlyings are less than or equal to expected retained, return\n if (usableUnderlyings <= expectedRetained) return;\n\n // Else, exceeding amount is equal to difference between those values\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= exceedingAmount;\n\n // Transfer the exceeding amount to the fund wallet\n underlying().safeTransfer(fund, exceedingAmount);\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L45\");\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\n * Use deposit() function instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L46\");\n }\n\n /**\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\n * @param amount The amount of underlying tokens to deposit.\n */\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough underlying tokens to deposit\n require(underlying().balanceOf(_msgSender()) >= amount, \"L47\");\n\n // Update usable underlyings balance accordingly\n usableUnderlyings += amount;\n\n // Inform listeners of the deposit activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Deposit,\n amount,\n amount,\n Status.Success,\n NO_ID\n );\n\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\n super.depositFor(_msgSender(), amount);\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\n * given amount.\n * @param account The account initiating the withdrawal.\n * @param amount The amount of the withdrawal.\n */\n function getWithdrawnAmountAndFees(\n address account,\n uint256 amount\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\n // If the account is eligible to staking tier 2, no fees are applied\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\n\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert amount and fees rate to SUD\n uint256 amountSUD = SUD.fromAmount(amount, d);\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\n\n // Compute fees and withdrawn amount (initial amount minus fees)\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\n fees = SUD.toAmount(feesSUD, d);\n withdrawnAmount = amount - fees;\n }\n\n /**\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\n * enough underlying tokens to cover the withdrawal.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestWithdrawal() function otherwise.\n * @param amount The amount L-Tokens to withdraw.\n */\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L48\");\n\n // Can the contract cover this withdrawal plus all already queued requests?\n bool cond1 = totalQueued + amount <= usableUnderlyings;\n\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\n\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\n if (!(cond1 || cond2)) revert(\"L49\");\n\n // Else, retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\n\n // Increase unclaimed fees amount accordingly\n unclaimedFees += fees;\n\n // Decrease usable underlyings balance accordingly\n usableUnderlyings -= withdrawnAmount;\n\n // Inform listeners of this instant withdrawal activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Withdraw,\n amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Burn withdrawal fees from the account\n _burn(_msgSender(), fees);\n\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\n super.withdrawTo(_msgSender(), withdrawnAmount);\n }\n\n /**\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\n * amount of underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n * @param amount The amount L-Tokens to withdraw.\n */\n function requestWithdrawal(\n uint256 amount\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L53\");\n\n // Ensure the requested amount doesn't overflow uint96\n require(amount <= type(uint96).max, \"L54\");\n\n // Ensure the sender attached the pre-paid processing gas fees\n require(msg.value == 0.003 * 10 ** 18, \"L55\");\n\n // Create withdrawal request data\n WithdrawalRequest memory request = WithdrawalRequest({\n account: _msgSender(),\n amount: uint96(amount)\n });\n\n // Will hold the request ID\n uint256 requestId;\n\n // Append request to the withdrawal queue:\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\n withdrawalQueueCursor--;\n requestId = withdrawalQueueCursor;\n withdrawalQueue[requestId] = request;\n }\n // - At the end else\n else {\n withdrawalQueue.push(request);\n requestId = withdrawalQueue.length - 1;\n }\n\n // Increase total amount queued accordingly\n totalQueued += amount;\n\n // Inform listeners of this new queued withdrawal activity event\n emit ActivityEvent(\n int256(requestId),\n _msgSender(),\n Action.Withdraw,\n amount,\n amount,\n Status.Queued,\n NO_ID\n );\n\n // Burn withdrawal L-Tokens amount from account's balance\n _burn(_msgSender(), amount);\n\n // Forward pre-paid processing gas fees to the withdrawer wallet\n (bool sent, ) = withdrawer.call{value: msg.value}(\"\");\n require(sent, \"L56\");\n }\n\n /**\n * @notice Processes queued withdrawal requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n * @dev For further details, see \"LToken > Withdrawals\" section of whitepaper.\n */\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\n // Accumulators variables, will be written on-chain after the loop\n uint256 cumulatedFees = 0;\n uint256 cumulatedWithdrawnAmount = 0;\n uint256 nextRequestId = withdrawalQueueCursor;\n\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\n // requests are increasing the queue length when moved at the end of the queue.\n uint256 queueLength = withdrawalQueue.length;\n\n // Iterate over requests to be processed\n while (nextRequestId < queueLength) {\n // Stop processing requests if there is not enough gas left to continue the\n // loop and properly end the function call. This prevents an attacker from\n // blocking the withdrawal processing by creating a ton of tiny requests so\n // this function call cannot fit anymore in block gas limit.\n if (gasleft() < 45000) break;\n\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\n\n // Skip empty request (processed big requests or cancelled requests)\n if (request.account == address(0)) {}\n //\n // If account has been blacklisted since request emission\n else if (isBlacklisted(request.account)) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request in the frozen requests list\n frozenRequests.push(request);\n }\n //\n // Or if request is a big request, move it at the end of the queue for now.\n // This request will be processed manually later using processBigQueuedRequest()\n else if (request.amount > getExpectedRetained() / 2) {\n // Inform listeners of this queued request being moved at the end of the queue\n emit ActivityEvent(\n int256(nextRequestId),\n _msgSender(),\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Moved,\n int256(withdrawalQueue.length)\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request at the end of the queue\n withdrawalQueue.push(request);\n }\n //\n // Else, continue request processing\n else {\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Break if the contract doesn't hold enough funds to cover the request\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\n\n // Accumulate fees and withdrawn amount\n cumulatedFees += fees;\n cumulatedWithdrawnAmount += withdrawnAmount;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(nextRequestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Transfer underlying tokens to account. Burning L-Tokens is not required\n // as equestWithdrawal() already did it.\n // Security note: Re-entrancy warning are disabled as the request has\n // just been deleted from the queue, it will so be skipped if trying to\n // process it again.\n // slither-disable-next-line reentrancy-no-eth\n underlying().safeTransfer(request.account, withdrawnAmount);\n }\n\n // Increment next request ID\n nextRequestId++;\n }\n\n // Increase unclaimed fees by the amount of cumulated fees\n unclaimedFees += cumulatedFees;\n\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\n usableUnderlyings -= cumulatedWithdrawnAmount;\n\n // Decrease total amount queued by the cumulated amount requested\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\n\n // Update new queue cursor\n withdrawalQueueCursor = nextRequestId;\n\n // Retention rate cannot exceeds as the withdrawal decreases both usable\n // underlyings and expected retained amounts by the same number and as the\n // expected retained amount is a subset of usable underlyings amount.\n }\n\n /**\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\n * the retention rate).\n * @dev In contrast to non-big requests processing, this function will uses to fund\n * wallet's balance to fill the request. This allows processing requests that are\n * greater than retention rate without having to exceed this rate on the contract.\n * @param requestId The ID of the big request to process.\n */\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure the request is active\n require(request.account != address(0), \"L66\");\n\n // Ensure the request emitter has not been blacklisted since request emission\n require(!isBlacklisted(request.account), \"L50\");\n\n // Ensure this is indeed a big request\n require(request.amount > getExpectedRetained() / 2, \"L51\");\n\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\n uint256 fundBalance = underlying().balanceOf(fund);\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \"L52\");\n\n // Increase amount of unclaimed fees accordingly\n unclaimedFees += fees;\n\n // Decrease total queued amount by request amount\n totalQueued -= request.amount;\n\n // Increment queue cursor if request was the next request to be processed\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[requestId];\n\n // If fund wallet's balance can cover request, rely on it only\n if (withdrawnAmount <= fundBalance) {\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\n }\n // Else, cover request from both fund wallet and contract balances\n else {\n // Compute amount missing from fund wallet to cover request\n uint256 missingAmount = withdrawnAmount - fundBalance;\n\n // Decrease usable amount of underlying tokens accordingly\n usableUnderlyings -= missingAmount;\n\n // Transfer entire fund balance to request's emitter\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\n\n // Transfer missing amount from contract balance to request emitter\n underlying().safeTransfer(request.account, missingAmount);\n }\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Cancels a given withdrawal request. The request emitter receive back its\n * L-Tokens and no fees will be charged.\n * @param requestId The ID of the withdrawal request to cancel.\n */\n function cancelWithdrawalRequest(\n uint256 requestId\n ) public whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure request belongs to caller\n require(_msgSender() == request.account, \"L57\");\n\n // Decrease total amount queued accordingly\n totalQueued -= request.amount;\n\n // Delete the withdrawal request from queue\n delete withdrawalQueue[requestId];\n\n // Inform listeners of this cancelled withdrawal request activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Cancelled,\n NO_ID\n );\n\n // Mint back L-Tokens to account\n _mint(request.account, uint256(request.amount));\n }\n\n /**\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\n * whenever those are required to fulfill some withdrawal requests.\n * @dev The function will revert if repatriated amount makes the contract exceeding\n * the retention rate.\n * @param amount The amount of underlying tokens to repatriate.\n */\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\n // Ensure the fund wallet has enough funds to repatriate\n require(amount <= underlying().balanceOf(fund), \"L58\");\n\n // Calculate new contract usable balance\n uint256 newBalance = usableUnderlyings + amount;\n\n // Ensure the new balance doesn't exceed the retention rate\n require(newBalance <= getExpectedRetained(), \"L59\");\n\n // Increase usable underlyings amount by repatriated amount\n usableUnderlyings += amount;\n\n // Transfer amount from fund wallet to contract\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /// @notice Used by owner to claim fees generated from successful withdrawals.\n function claimFees() external onlyOwner {\n // Ensure there are some fees to claim\n require(unclaimedFees > 0, \"L60\");\n\n // Ensure the contract holds enough underlying tokens to cover fees\n require(usableUnderlyings >= unclaimedFees, \"L61\");\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= unclaimedFees;\n\n // Store fees amount in memory and reset unclaimed fees amount\n uint256 fees = unclaimedFees;\n unclaimedFees = 0;\n\n // Transfer unclaimed fees to owner\n underlying().safeTransfer(owner(), fees);\n }\n}\n" + }, + "contracts/src/LTokenSignaler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title LTokenSignaler\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Used to inform subgraph from the existence of a new L-Token contract. Once\n * signaled, a L-Token will start being indexed.\n *\n * @dev Signal are ignored by the subgraph if the L-Token is already known by it.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LTokenSignaler is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Emitted to inform subgraph of the existence of a new L-Token contract.\n * @param lTokenAddress The address of the L-Token contract to signal.\n */\n event LTokenSignalEvent(address indexed lTokenAddress);\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Signals a LToken contract to the TheGraph subgraph of the current chain.\n * @param lTokenAddress The address of the LToken contract to signal.\n */\n function signalLToken(address lTokenAddress) external onlyOwner {\n // Signal the LToken contract\n emit LTokenSignalEvent(lTokenAddress);\n }\n}\n" + }, + "contracts/src/PreMining.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {LToken} from \"./LToken.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\n/**\n * @title PreMining\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n\n * @notice PreMining pool contract, allowing accounts to lock underlying tokens in a \n * pre-defined L-Token contract, over a given duration (in months), in exchange of \n * vested LDY rewards.\n * \n * @dev Intuition\n * \n * Lifecycle of a lockdrop pool is composed by 3 main phases:\n * 1) Deposit: During this phase, users can lock their underlying tokens.\n * 2) Claim: During this phase, users can claim their LDY rewards.\n * 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract.\n * \n * Transitioning between two phases is manually triggered by contract's owner.\n * To ensure fair usage of this power and prevent potential misuse:\n * - the Recovery phase cannot start before 3 months after the end of rewards vesting,\n * - the Recovery phase cannot start before 3 months after the maximum lock end.\n * \n * Finally, note that this contract proxies main L-Token contract's functions:\n * - lock() --> deposit()\n * - instantUnlock() --> instantWithdrawal()\n * - requestUnlock() --> requestWithdrawal()\n * This design enables users to interact with the PreMining contract in a similar fashion\n * to the L-Token contract.\n * \n * @dev Definitions:\n * - Locker: An account that has locked underlying tokens in the pool.\n * \n * @custom:security-contact security@ledgity.com\n */\ncontract PreMining is Ownable2Step, Pausable {\n using SafeERC20 for IERC20;\n\n /**\n * @notice Represents the lock information of an account.\n * @param amount Amount of underlying tokens locked.\n * @param duration Duration of the lock (in months).\n * @param hasUnlocked Whether the account has unlocked its locked tokens.\n * @param claimedRewards Amount of LDY rewards already claimed.\n * @param lockEndTimestamp Timestamp at which the account's lock ends.\n */\n struct AccountLock {\n uint240 amount;\n uint8 duration;\n bool hasUnlocked;\n uint216 claimedRewards;\n uint40 lockEndTimestamp;\n }\n\n /// @notice Holds the amount of LDY to be distributed to lockers.\n uint256 public immutable maxDistributedLDY;\n\n /// @notice Holds the maximum total amount of L-Tokens that can be locked.\n uint256 public immutable lockedHardCap;\n\n /// @notice Holds the minimum possible lock duration (in months).\n uint8 public immutable minLockDuration;\n\n /// @notice Holds the maximum possible lock duration (in months).\n uint8 public immutable maxLockDuration;\n\n /// @notice Holds the duration of LDY rewards vesting (in months).\n uint8 public immutable vestingDuration;\n\n /// @notice Holds a reference to the locked L-Token contract.\n LToken public immutable lToken;\n\n /// @notice Holds a reference to the L-Token underlying stablecoin.\n IERC20 public immutable underlyingToken;\n\n /// @notice Holds the max pool weight.\n uint256 public immutable maxWeight;\n\n /// @notice Holds a reference to the LDY token contract.\n IERC20 public ldyToken;\n\n /// @notice Holds lockers' participations informations.\n mapping(address => AccountLock) public accountsLocks;\n\n /// @notice Holds the total amount of locked underlying tokens.\n uint256 public totalLocked;\n\n /// @notice Holds whether the Deposit phase has ended.\n bool public hasDepositPhaseEnded;\n\n /// @notice Holds whether the Claim phase has started.\n bool public hasClaimPhaseStarted;\n\n /// @notice Holds whether the Recovery phase has started.\n bool public hasRecoveryPhaseStarted;\n\n /// @notice Holds the timestamp at which the Claim phase started.\n uint256 public claimPhaseStartTimestamp;\n\n /// @notice Holds an ordered queue of accounts that requested to unlock their tokens.\n address[] public unlockRequests;\n\n /// @notice Holds the index of the first request in the queue (a.k.a, next one to be processed).\n uint256 public unlockRequestsCursor;\n\n /// @notice Emitted to inform about a new lock/deposit.\n event Lock(address indexed account, uint256 amount, uint8 duration);\n\n /// @notice Top-level checks and code shared by both unlock functions.\n modifier safeUnlock() {\n // Ensure that the account's lock has ended\n require(accountsLocks[msg.sender].lockEndTimestamp <= block.timestamp, \"L68\");\n\n // Ensure the account hasn't already unlocked its tokens\n require(!accountsLocks[msg.sender].hasUnlocked, \"L69\");\n\n // Ensure the account has something to unlock\n require(accountsLocks[msg.sender].amount > 0, \"L70\");\n\n // Indicate that account has unlocked its tokens\n accountsLocks[msg.sender].hasUnlocked = true;\n _;\n }\n\n /**\n * @notice This constructor function etches the lockdrop terms in immutable states.\n * Ensuring that those terms cannot be modified after deployment.\n * @param lTokenAddress_ Address of the L-Token contract to use.\n * @param maxDistributedLDY_ Amount of LDY to be distributed to lockers.\n * @param lockedHardCap_ Maximum total amount of L-Tokens that can be locked.\n * @param minLockDuration_ Minimum possible lock duration (in months).\n * @param maxLockDuration_ Maximum possible lock duration (in months).\n * @param vestingDuration_ Duration of LDY rewards vesting (in months).\n */\n constructor(\n address lTokenAddress_,\n uint256 maxDistributedLDY_,\n uint256 lockedHardCap_,\n uint8 minLockDuration_,\n uint8 maxLockDuration_,\n uint8 vestingDuration_\n ) {\n // Ensure minLockDuration is at least 1 month\n require(minLockDuration_ >= 1, \"L72\");\n\n // Ensure minLockDuration is not greater than maxLockDuration\n require(minLockDuration_ <= maxLockDuration_, \"L73\");\n\n // Set immutable states\n lToken = LToken(lTokenAddress_);\n underlyingToken = IERC20(address(lToken.underlying()));\n lockedHardCap = lockedHardCap_;\n maxDistributedLDY = maxDistributedLDY_;\n minLockDuration = minLockDuration_;\n maxLockDuration = maxLockDuration_;\n vestingDuration = vestingDuration_;\n maxWeight = lockedHardCap * uint256(maxLockDuration);\n }\n\n /**\n * @notice Public implementation of Pausable's pausing and unpausing functions, but\n * restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Updates the LDY token contract address.\n * @dev As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE,\n * this function allows the contract's owner to set the LDY token address once it\n * becomes available.\n * @param ldyTokenAddress Address of the LDY token contract.\n */\n function setLDYToken(address ldyTokenAddress) external onlyOwner {\n // Prevent owner from changing the LDY address after Claim phase has started\n require(!hasClaimPhaseStarted, \"L74\");\n\n // Set LDY token address\n ldyToken = IERC20(ldyTokenAddress);\n }\n\n /**\n * @notice Closes the Deposit phase. After calling this function, account won't be\n * able to lock additional underlying tokens anymore.\n */\n function endDepositPhase() external onlyOwner {\n hasDepositPhaseEnded = true;\n }\n\n /**\n * @notice Opens the Claim phase. After calling this function, lockers will be able\n * to start claiming their LDY rewards.\n */\n function startClaimPhase() external onlyOwner {\n // Ensure Claim phase has not already started\n require(!hasClaimPhaseStarted, \"L76\");\n\n // Ensure that LDY token address is available\n require(address(ldyToken) != address(0), \"L77\");\n\n // Set Claim phase as started and store the start timestamp\n hasClaimPhaseStarted = true;\n claimPhaseStartTimestamp = block.timestamp;\n }\n\n /**\n * @notice Opens the Recovery phase. After calling this function, the contract owner\n * will be able to recover remaining ERC20 tokens on the contract.\n * Note that this won't close the Claim phase and lockers will still be able to claim\n * their LDY rewards.\n */\n function startRecoveryPhase() external onlyOwner {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L79\");\n\n // Compute some durations in seconds\n uint256 threeMonthsInSecond = 3 * 30 days;\n uint256 vestingInSecond = uint256(vestingDuration) * 30 days;\n uint256 maxLockInSecond = uint256(maxLockDuration) * 30 days;\n\n // Compute timestamp of vesting end + 3 months\n uint256 afterVestingTimestamp = claimPhaseStartTimestamp +\n vestingInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the end of reward vesting\n // This prevents owner from recovering LDY before lockers can claim their rewards\n require(block.timestamp >= afterVestingTimestamp, \"L80\");\n\n // Compute end of maximum lock + 3 months\n // Note that claimPhaseStartTimestamp is used for simplicity even if it can exist a time\n // span between Deposit and Claim phases.\n uint256 afterMaxLockTimestamp = claimPhaseStartTimestamp +\n maxLockInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the maximum lock end\n // This prevents owner from recovering underlying tokens before lockers can unlock those\n require(block.timestamp >= afterMaxLockTimestamp, \"L81\");\n\n // Set recovery phase as started\n hasRecoveryPhaseStarted = true;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address. Will revert if\n * recovery phase has not started yet or if the contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\n // Ensure recovery phase has started\n require(hasRecoveryPhaseStarted, \"L82\");\n\n // Create a reference to token's contract\n IERC20 tokenContract = IERC20(tokenAddress);\n\n // Ensure there is enough tokens to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L83\");\n\n // Transfer the recovered token amount to the sender (owner)\n tokenContract.safeTransfer(msg.sender, amount);\n }\n\n /**\n * @notice Compute the total amount of LDY rewards that a given account is eligible to.\n * @dev Note: This function neither considers vesting nor already claimed rewards.\n * @param account The account to compute the eligible rewards of.\n * @return The total amount of LDY rewards that the account is eligible to.\n */\n function eligibleRewardsOf(address account) public view returns (uint256) {\n // Compute account's lock weight\n uint256 lockerWeight = accountsLocks[account].amount * accountsLocks[account].duration;\n\n // Compute amount of LDY that this locker is eligible to\n if (maxWeight == 0) return 0;\n else return (maxDistributedLDY * lockerWeight) / maxWeight;\n }\n\n /**\n * @notice Allows locking a specified amount of underlying tokens for a given duration.\n * By locking, an account became eligible to a portion of the distributed LDY rewards.\n * @dev This function proxies LToken.deposit()\n * @dev Lockers can extend their lock duration by calling this function again with a\n * greater duration and 0 as amount.\n * @param amount Amount of underlying tokens to lock.\n * @param duration Duration of the lock (in months).\n */\n function lock(uint256 amount, uint8 duration) external whenNotPaused {\n // Ensure Deposit phase has not ended yet\n require(!hasDepositPhaseEnded, \"L84\");\n\n // Ensure account hasn't already unlocked a past lock\n require(!accountsLocks[msg.sender].hasUnlocked, \"L71\");\n\n // Ensure lock duration is in valid range\n require(duration >= minLockDuration && duration <= maxLockDuration, \"L85\");\n\n // Ensure it won't exceed the hardcap\n require(totalLocked + amount <= uint256(lockedHardCap), \"L86\");\n\n // Increase account's locked amount\n accountsLocks[msg.sender].amount += uint240(amount);\n\n // Increase total locked amount accordingly\n totalLocked += amount;\n\n // Use existing lock duration if greater than the new one\n uint8 existingDuration = accountsLocks[msg.sender].duration;\n uint8 appliedDuration = existingDuration > duration ? existingDuration : duration;\n\n // Update account's lock duration\n accountsLocks[msg.sender].duration = appliedDuration;\n\n // Update account's lock end timestamp\n accountsLocks[msg.sender].lockEndTimestamp = uint40(\n block.timestamp + uint40(appliedDuration) * 30 days\n );\n\n // Emit a Lock event\n emit Lock(msg.sender, amount, appliedDuration);\n\n // If amount is 0, skip deposit\n if (amount == 0) return;\n\n // Transfer underlyingToken from account to contract\n underlyingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n // Deposit USDC in the L-Token contract\n underlyingToken.safeApprove(address(lToken), amount);\n lToken.deposit(amount);\n }\n\n /**\n * @notice Allows the caller to instaneously unlock its locked amount of underlying\n * tokens.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestUnlock() function otherwise.\n */\n function instantUnlock() external whenNotPaused safeUnlock {\n // Retrieve underlying tokens from the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.instantWithdrawal(unlockedAmount);\n\n // Transfer underlying tokens back to caller\n underlyingToken.safeTransfer(msg.sender, unlockedAmount);\n }\n\n /**\n * @notice Allows the call to request for the unlocking of its locked amount of\n * underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n */\n function requestUnlock() external payable whenNotPaused safeUnlock {\n // Put account in the unlock requests queue\n unlockRequests.push(msg.sender);\n\n // Request underlying tokens to the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.requestWithdrawal{value: msg.value}(unlockedAmount);\n }\n\n /**\n * @notice Processes queued unlock requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n */\n function processUnlockRequests() external onlyOwner {\n // Store the current request ID to process\n uint256 processedId = unlockRequestsCursor;\n\n // Loop over remaining requests\n while (processedId < unlockRequests.length) {\n // Prevent OOG by stopping request processing if there is not enough gas left\n // to continue the loop and properly end the function call.\n if (gasleft() < 45000) break;\n\n // Retrieve the request account\n address unlockAccount = unlockRequests[processedId];\n\n // Retrieve the unlocked amount\n uint256 unlockAmount = accountsLocks[unlockAccount].amount;\n\n // If the request has already been processed, skip it\n if (unlockAccount != address(0)) {\n // If the contract doesn't hold enough underlying tokens to process the request, stop here\n if (underlyingToken.balanceOf(address(this)) < unlockAmount) break;\n\n // Delete the request\n delete unlockRequests[processedId];\n\n // Transfer underlying back to account\n underlyingToken.safeTransfer(unlockAccount, unlockAmount);\n }\n\n // Increment processed request ID\n processedId++;\n }\n\n // Write back the cursor in storage\n unlockRequestsCursor = processedId;\n }\n\n /**\n * @notice Computes the amount of LDY rewards available to claim for a given account.\n * @dev This function considers vesting and already claimed rewards.\n * @param account The account to compute the available rewards of.\n * @return The amount of LDY rewards available to claim.\n */\n function availableToClaim(address account) public view returns (uint256) {\n // Compute total amount of rewards allocated to this locker\n uint256 totalEligibleRewards = eligibleRewardsOf(account);\n\n // Compute vesting duration in seconds\n uint256 vestingInSeconds = uint256(vestingDuration) * 30 days;\n\n // Compute elapsed months since claim phase started, and cap it to vesting duration\n uint256 elapsedTime = block.timestamp - claimPhaseStartTimestamp;\n if (elapsedTime > vestingInSeconds) elapsedTime = vestingInSeconds;\n\n // Compute total available to claim (proportionally to elapsed time)\n uint256 totalAvailableToClaim = (totalEligibleRewards * elapsedTime) / vestingInSeconds;\n\n // Else return net claimable (available minus already claimed)\n return totalAvailableToClaim - accountsLocks[account].claimedRewards;\n }\n\n /// @notice Allows the caller to claim its available LDY rewards.\n function claimRewards() external whenNotPaused {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L87\");\n\n // Compute claimable LDY rewards\n uint256 claimableLDY = availableToClaim(msg.sender);\n\n // Increase account claimed amount accordingly\n accountsLocks[msg.sender].claimedRewards += uint216(claimableLDY);\n\n // Transfer rewards to account\n ldyToken.safeTransfer(msg.sender, claimableLDY);\n }\n}\n" + } + }, + "settings": { + "evmVersion": "london", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/contracts/hardhat/deployments/localhost/solcInputs/3d20376140786af30d287ee442e9b474.json b/contracts/hardhat/deployments/localhost/solcInputs/3d20376140786af30d287ee442e9b474.json new file mode 100644 index 00000000..0aace587 --- /dev/null +++ b/contracts/hardhat/deployments/localhost/solcInputs/3d20376140786af30d287ee442e9b474.json @@ -0,0 +1,177 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeTo(address newImplementation) public virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../security/PausableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract unpausable.\n */\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\n function __ERC20Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../utils/SafeERC20Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the ERC20 token contract to support token wrapping.\n *\n * Users can deposit and withdraw \"underlying tokens\" and receive a matching number of \"wrapped tokens\". This is useful\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\n * wrapping of an existing \"basic\" ERC20 into a governance token.\n *\n * _Available since v4.2._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\n IERC20Upgradeable private _underlying;\n\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n __ERC20Wrapper_init_unchained(underlyingToken);\n }\n\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n require(underlyingToken != this, \"ERC20Wrapper: cannot self wrap\");\n _underlying = underlyingToken;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n */\n function decimals() public view virtual override returns (uint8) {\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\n return value;\n } catch {\n return super.decimals();\n }\n }\n\n /**\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\n */\n function underlying() public view returns (IERC20Upgradeable) {\n return _underlying;\n }\n\n /**\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\n */\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\n address sender = _msgSender();\n require(sender != address(this), \"ERC20Wrapper: wrapper can't deposit\");\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/src/abstracts/base/BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"../GlobalOwnableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"../GlobalRestrictableUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../RecoverableUpgradeable.sol\";\n\n/**\n * @title BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract acts as a base for numerous contracts in this codebase,\n * minimizing code repetition and enhancing readability and maintainability.\n *\n * @dev For further details, see \"Base\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract BaseUpgradeable is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n GlobalPausableUpgradeable,\n GlobalRestrictableUpgradeable,\n RecoverableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_\n ) internal onlyInitializing {\n __UUPSUpgradeable_init();\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n __Recoverable_init_unchained();\n }\n\n function __Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/base/ERC20BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport {ERC20PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"./BaseUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\n\n/**\n * @title ERC20BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract is an extension of BaseUpgradeable intended to be used\n * as a base for ERC20 tokens contracts.\n *\n * @dev For further details, see \"ERC20BaseUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract ERC20BaseUpgradeable is\n ERC20Upgradeable,\n BaseUpgradeable,\n ERC20PausableUpgradeable\n{\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param name_ The display name of the token.\n * @param symbol_ The symbol of the token.\n */\n function __ERC20Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n string memory name_,\n string memory symbol_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __ERC20_init(name_, symbol_);\n __ERC20Pausable_init_unchained();\n }\n\n function __ERC20Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\n * state from the GlobalPause contract.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, PausableUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\n * The ERC20PausableUpgradeable version is preferred because it also checks that\n * the contract is not paused before allowing the transfer.\n * @inheritdoc ERC20PausableUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n virtual\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\n whenNotPaused\n notBlacklisted(from)\n notBlacklisted(to)\n {\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalOwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {GlobalOwner} from \"../GlobalOwner.sol\";\n\n/**\n * @title GlobalOwnableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\n * contract (see GlobalOwner.sol). This design facilitates centralized management\n * of ownership for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalOwner state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalOwnableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\n /**\n * @notice The GlobalOwner contract the ownership will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalOwner private _globalOwner;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init_unchained(globalOwner_);\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\n // the initial _owner value, calling it would have no effect.\n }\n\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\n _globalOwner = GlobalOwner(globalOwner_);\n }\n\n /**\n * @notice Retrieves the address of GlobalOwner contract.\n * @return The address of the GlobalOwner contract.\n */\n function globalOwner() public view returns (address) {\n return address(_globalOwner);\n }\n\n /**\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\n * from the GlobalOwner contract instead.\n * @return The address of the owner\n */\n function owner() public view override returns (address) {\n return _globalOwner.owner();\n }\n\n /**\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function transferOwnership(address newOwner) public view override onlyOwner {\n newOwner; // Silence unused variable compiler warning\n revert(\"L8\");\n }\n\n /**\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function renounceOwnership() public view override onlyOwner {\n revert(\"L65\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalPausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalPause} from \"../GlobalPause.sol\";\n\n/**\n * @title GlobalPausableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a pause state from the specified GlobalPause\n * contract (see GlobalPause.sol). This design facilitates centralized management of\n * pause state for all the Ledgity Yield contracts.\n *\n * @dev Security measure\n * The _globalPause state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalPausableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\n /**\n * @notice The GlobalPause contract the pause state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalPause private _globalPause;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalPause_ The address of the GlobalPause contract.\n */\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n }\n\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\n _globalPause = GlobalPause(globalPause_);\n }\n\n /**\n * @notice Retrieves the address of GlobalPause contract.\n * @return The address of the GlobalPause contract.\n */\n function globalPause() public view returns (address) {\n return address(_globalPause);\n }\n\n /**\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\n * from the GlobalPause contract instead.\n * @return Whether the contract is paused or not.\n */\n function paused() public view virtual override returns (bool) {\n return _globalPause.paused();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalRestrictableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalBlacklist} from \"../GlobalBlacklist.sol\";\n\n/**\n * @title GlobalRestrictableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a blacklist state from the specified\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\n * centralized management of a blacklist for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalBlacklist state must be set at initialization time and, for evident\n * security reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalRestrictableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalRestrictableUpgradeable is Initializable {\n /**\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalBlacklist private _globalBlacklist;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n }\n\n function __GlobalRestrictable_init_unchained(\n address globalBlacklist_\n ) internal onlyInitializing {\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\n }\n\n /**\n * @notice Retrieves the address of GlobalBlacklist contract.\n * @return The address of the GlobalBlacklist contract.\n */\n function globalBlacklist() public view returns (address) {\n return address(_globalBlacklist);\n }\n\n /**\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n */\n modifier notBlacklisted(address account) {\n require(isBlacklisted(account) == false, \"L9\");\n _;\n }\n\n /**\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n * @return Whether the account is blacklisted.\n */\n function isBlacklisted(address account) internal view returns (bool) {\n return _globalBlacklist.isBlacklisted(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/InvestUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"./GlobalPausableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"./GlobalRestrictableUpgradeable.sol\";\nimport \"./base/BaseUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../abstracts/RecoverableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {APRHistory as APRH} from \"../libs/APRHistory.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title InvestUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with utilities to manage an invested token,\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\n *\n * @dev Intuition:\n * This contract primarily exists for code splitting and reusability. It unburdens the\n * LToken contract code, making it easier to understand and maintain.\n *\n * This contract is generic because it may be used in the LDYStaking contract in the future.\n *\n * @dev Definitions:\n * - Investment: The act of depositing or investing tokens into the contract.\n * - Investment period: Time between the last invested amount change and the present.\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\n * distributed between investment periods.\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\n *\n * @dev Derived contract must:\n * - Set invested token during initialization\n * - Implement _investmentOf() function\n * - (optionally) Implement _distributeRewards() function\n *\n * @dev For further details, see \"InvestmentUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract InvestUpgradeable is BaseUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using APRH for APRH.Pack[];\n\n /**\n * @notice Represents an account's investment period.\n * @param timestamp The timestamp of the most recent rewards distribution.\n * @param ref The reference of the last APR checkpoint at that timestamp.\n */\n struct InvestmentPeriod {\n uint40 timestamp; // Supports dates up to 20/02/36812\n APRH.Reference ref;\n }\n\n /**\n * @notice Represents the investment details of an account.\n * @param period The current investment period of the account.\n * @param virtualBalance May hold a part of account rewards until they are claimed.\n */\n struct AccountDetails {\n InvestmentPeriod period;\n uint256 virtualBalance;\n }\n\n /// @notice Holds a reference to the invested token's contract.\n IERC20Upgradeable private _invested;\n\n /// @notice Holds investment details of each account.\n mapping(address => AccountDetails) internal accountsDetails;\n\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\n APRH.Pack[] private _aprHistory;\n\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\n mapping(address => address) public rewardsRedirectsFromTo;\n mapping(address => address[]) public rewardsRedirectsToFrom;\n\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\n bool private _isClaiming;\n\n /**\n * @notice Emitted to inform listeners about a change in the APR's value.\n * @param newAPRUD7x3 The new APR in UD7x3 format.\n */\n event APRChangeEvent(uint16 newAPRUD7x3);\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param invested_ The address of the invested token contract.\n */\n function __Invest_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address invested_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __Invest_init_unchained(invested_);\n }\n\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\n // Set invested token\n _invested = IERC20Upgradeable(invested_);\n\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\n // of an empty APR history\n _aprHistory.setAPR(0);\n }\n\n /**\n * @notice Retrieves the reference to the invested token contract.\n * @return The reference to the invested token contract.\n */\n function invested() public view returns (IERC20Upgradeable) {\n return _invested;\n }\n\n /**\n * @notice Updates the investment APR. Restricted to owner.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(uint16 aprUD7x3) public onlyOwner {\n _aprHistory.setAPR(aprUD7x3);\n emit APRChangeEvent(aprUD7x3);\n }\n\n /**\n * @notice Retrieves the most recently set APR.\n * @return The current APR in UD7x3 format.\n */\n function getAPR() public view returns (uint16) {\n return _aprHistory.getAPR();\n }\n\n /**\n * @notice Enables redirection of rewards from one account to another.\n * @param from The address of the account to redirect rewards from.\n * @param to The address of the account to redirect rewards to.\n */\n function startRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure the address is not already redirecting rewards\n require(rewardsRedirectsFromTo[from] == address(0), \"L62\");\n\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L12\");\n require(to != address(0), \"L13\");\n\n // Ensure 'from' and 'to' addresses are distinct\n require(from != to, \"L14\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L15\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Activate rewards redirection\n rewardsRedirectsFromTo[from] = to;\n rewardsRedirectsToFrom[to].push(from);\n }\n\n /**\n * @notice Disable an active rewards redirection.\n * @param from The address of the account to stop redirecting rewards from.\n * @param to The address of the account to stop redirecting rewards to.\n */\n function stopRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L16\");\n require(to != address(0), \"L17\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L18\");\n\n // Ensure a rewards redirection was active\n require(rewardsRedirectsFromTo[from] == to, \"L19\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Retrieve 'from' index in the redirection array of 'to'\n int256 fromIndex = -1;\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\n if (rewardsRedirectsToFrom[to][i] == from) {\n fromIndex = int256(i);\n break;\n }\n }\n\n // fromIndex should never be -1 at this point\n assert(fromIndex >= 0);\n\n // Deactivate rewards redirection\n rewardsRedirectsFromTo[from] = address(0);\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\n rewardsRedirectsToFrom[to].length - 1\n ];\n rewardsRedirectsToFrom[to].pop();\n }\n\n /**\n * @notice Retrieves the total amount of tokens invested by the given account.\n * @dev Derived contracts must implement this function.\n * @param account The account to get the investment of.\n * @return The total amount of tokens invested by the given account.\n */\n function _investmentOf(address account) internal view virtual returns (uint256);\n\n /**\n * @notice Distributes a specified amount of rewards to a given account.\n * @dev Derived contracts may optionally implement this function.\n * @dev Implementations must return true to indicate a successful distribution, and\n * false otherwise. If it returns false, the rewards will be added to the account's\n * virtual balance, in order to be claimed later.\n * @param account The account to claim the rewards of.\n * @param amount The amount of rewards to claim.\n * @return Whether the rewards distribution was successfull.\n */\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\n account; // Silence unused variables warning\n amount;\n return false;\n }\n\n /**\n * @notice Computes the rewards accrued over a specified period of time, based on a\n * given APR and amount of invested tokens.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param beginTimestamp The moment the period commenced.\n * @param endTimestamp The moment the period concluded.\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\n * @param investedAmount The amount of tokens deposited/invested during the period.\n * @return The amount of rewards generated during the period.\n */\n function _calculatePeriodRewards(\n uint40 beginTimestamp,\n uint40 endTimestamp,\n uint16 aprUD7x3,\n uint256 investedAmount\n ) internal view returns (uint256) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Compute the number of elapsed years\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\n\n // Compute the growth in invested amount (thanks to rewards)\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\n\n // Compute and return the rewards\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(rewardsSUD, d);\n }\n\n /**\n * @notice Computes the sum of given account's invested amount, plus invested amount\n * of all accounts that recursively redirect rewards to this account.\n * @param account The account to calculate the deep investment of.\n * @return deepInvestedAmount The deep invested amount.\n */\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\n // Consider account's direct investment\n deepInvestedAmount += _investmentOf(account);\n\n // But also the deep investments of all accounts redirecting rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param account The account to calculate the unclaimed rewards of.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\n */\n function _rewardsOf(\n address account,\n bool autocompound\n ) internal view returns (uint256 rewards) {\n // Retrieve account's investment details\n AccountDetails memory details = accountsDetails[account];\n\n // Retrieve account's deep invested amount\n uint256 investedAmount = _deepInvestmentOf(account);\n\n // Return 0 if the account has never invested or has no invested amount\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\n\n // Retrieve reference and data of APR checkpoint at which started investment period\n APRH.Reference memory currRef = details.period.ref;\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\n\n // Retrieve reference of latest APR checkpoint\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\n\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\n // See \"InvestUpgradeable > Yield calculation > 1)\" section of the whitepaper\n rewards = details.virtualBalance;\n\n // If start checkpoint is not the latest one\n if (!APRH.eq(currRef, latestRef)) {\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // 2) Calculate rewards from investment period start to next checkpoint\n // See \"InvestUpgradeable > Yield calculation > 2)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n\n // 3) Calculate rewards for each crossed pair of checkpoints\n // See \"InvestUpgradeable > Yield calculation > 3)\" section of the whitepaper\n while (true) {\n // Set next checkpoint as the current one\n currRef = nextRef;\n currCheckpoint = nextCheckpoint;\n\n // Break if current checkpoint is the latest one\n if (APRH.eq(currRef, latestRef)) break;\n\n // Else, retrieve the new next checkpoint\n nextRef = APRH.incrementReference(currRef);\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // Calculate rewards between the current pair of checkpoints\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n\n // 4) Calculate rewards from the latest checkpoint to now\n // See \"InvestUpgradeable > Yield calculation > 4)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n } else {\n // 2.bis) Calculate rewards from investment period start to now\n // See \"InvestUpgradeable > Yield calculation > 2.bis)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n }\n\n /**\n * @notice Recursively resets the investment period of the specified account and of\n * all accounts that directly or indirectly redirect rewards to this account.\n * @param account The account to deeply reset the investment period of.\n */\n function _deepResetInvestmentPeriodOf(address account) internal {\n // Reset account investment period timestamp and APR checkpoint to latest ones\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\n\n // Also reset the ones of all accounts that recursively redirect rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Hook to be invoked before the invested amount of an account changes. It\n * ensures that rewards are distributed and that account's investment period is reset.\n * @param account The account whose invested amount is going to change.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n */\n function _beforeInvestmentChange(address account, bool autocompound) internal {\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\n // minted in LToken._distributeRewards(), this guards against infinite loop.\n if (_isClaiming) return;\n\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\n // As first call will treat both addresses, the second call would be redundant.\n // Therefore, we skip accounts already processed in this block to save up some gas.\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\n\n // If account redirects its rewards\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\n if (redirectRewardsTo != address(0)) {\n // Call hook on redirection target (this will indirectly reset the investment\n // of this source account) and return\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\n return;\n }\n\n // Else, compute account's undistributed/unclaimed rewards\n uint256 rewards = _rewardsOf(account, autocompound);\n\n // If there are some rewards\n if (rewards > 0) {\n // Try to distribute rewards to account\n _isClaiming = true;\n bool distributed = _distributeRewards(account, rewards);\n _isClaiming = false;\n\n // If rewards have not been distributed, accumulate them in account's virtual balance\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\n }\n\n // Finally, deeply reset investment period of the account\n _deepResetInvestmentPeriodOf(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/RecoverableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Conracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title RecoverableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with helper functions allowing the recovery of\n * assets accidentally sent to them.\n *\n * @dev Where are utilities Ether, ERC721, etc.?\n * This abstract contract currently supports only ERC20 tokens. Derived contracts\n * in this codebase currently do not implement the necessary functions to receive Ether\n * or ERC721/ERC1155 tokens, so no recovery functions are provided for these assets.\n *\n * @dev For further details, see \"RecoverableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init(globalOwner_);\n __Recoverable_init_unchained();\n }\n\n function __Recoverable_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Recovers a specified amount of a given token address. Will fail if the\n * contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\n // Ensure the specified amount is not zero\n require(amount > 0, \"L10\");\n\n // Create a reference to token's contract\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\n\n // Ensure there is enough token to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L11\");\n\n // Transfer the recovered token amount to the sender\n tokenContract.safeTransfer(_msgSender(), amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/DummyLDYStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title LDYStaking\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This contract acts as a placeholder for the real LDYStaking contract until\n * this one is deployed.\n *\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\n * one the LToken contract relies on.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LDYStaking is Ownable2Step {\n /**\n * @notice Holds a mapping of addresses that default to the highest staking tier.\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\n */\n mapping(address => bool) public highTierAccounts;\n\n /**\n * @notice Update high tier status of a given account.\n * @param account The account to update the high tier status of.\n */\n function setHighTierAccount(address account, bool status) public onlyOwner {\n highTierAccounts[account] = status;\n }\n\n /**\n * @dev Dummy tierOf() function that always return that the given account is not\n * elligible to any LDY staking tier, except if the account is in the\n * highTierAccounts mapping.\n * @param account The account to check the tier of.\n */\n function tierOf(address account) public view returns (uint256 tier) {\n if (highTierAccounts[account]) return 3;\n return 0;\n }\n}\n" + }, + "contracts/src/GenericERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n/**\n * @notice Used for testing purposes only, and used to generate ABIs for Wagmi contracts calls.\n * It represents:\n * - a FIAT-based stablecoin when used to test the LToken contract,\n * - the $LDY token when used to test the LDYStaking contract.\n * This contract accept decimals as constructor argument, so it can be used to to\n * easily test different decimals scenarios.\n */\ncontract GenericERC20 is ERC20, ERC20Burnable {\n uint8 private _decimals;\n\n constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) {\n _decimals = decimals_;\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n\n /**\n * Used in tests to test different decimals scenarios.\n */\n function setDecimals(uint8 decimals_) public {\n _decimals = decimals_;\n }\n}\n" + }, + "contracts/src/GlobalBlacklist.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalBlacklist\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global mapping of blacklisted accounts shared by all contracts of the\n * Ledgity Yield codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\n * and getter functions to easily check against this global blacklist.\n *\n * @dev For further details, see \"GlobalBlacklist\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Mapping of accounts to their blacklist status.\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\n */\n mapping(address => bool) private _list;\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Adds a given account to the blacklist.\n * @param account The account's address to be blacklisted.\n */\n function blacklist(address account) external onlyOwner {\n require(account != address(0), \"L20\");\n _list[account] = true;\n }\n\n /**\n * @notice Removes a given account from the blacklist.\n * @param account The account's address to be un-blacklisted.\n */\n function unBlacklist(address account) external onlyOwner {\n _list[account] = false;\n }\n\n /**\n * @notice Checks whether a given account is blacklisted.\n * @param account Address of the account to check.\n * @return 'true' if the account is blacklisted, 'false' otherwise\n */\n function isBlacklisted(address account) external view returns (bool) {\n // Gas optimization: Avoid accessing storage if account is the zero address\n // (e.g, during a mint or a burn of tokens)\n if (account == address(0)) return false;\n\n // Else, return current account's blacklist status\n return _list[account];\n }\n}\n" + }, + "contracts/src/GlobalOwner.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\n/**\n * @title GlobalOwner\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds the address of a global owner account shared by all contracts of the\n * Ledgity Yield's codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\n * owner() function that retrieves the owner's address from this contract instead.\n *\n * @dev For further details, see \"GlobalOwner\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize() public initializer {\n __Ownable2Step_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n}\n" + }, + "contracts/src/GlobalPause.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalPause\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global pause state shared by all contracts of the Ledgity Yield\n * codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\n * paused() function that retrieves the pause state from this contract instead.\n *\n * @dev For further details, see \"GlobalPause\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalPause is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n PausableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\n * but restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n}\n" + }, + "contracts/src/interfaces/ITransfersListener.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\ninterface ITransfersListener {\n function onLTokenTransfer(address from, address to, uint256 amount) external;\n}\n" + }, + "contracts/src/libs/APRHistory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n/**\n * @title APRHistory\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This library offers utilities to efficiently maintain the history of an\n * on-chain APR (Annual Percentage Rate) state. Each entry in this history is called\n * a \"checkpoint\".\n *\n * @dev Intuition:\n * Each checkpoint in an APR history consists of two data:\n * - the creation timestamp\n * - the APR at that time\n *\n * Given that reading and writing to storage slots are among the most costly operations\n * in Solidity, this library provides a way to store those data in a way that minimizes\n * the number of used storage slots.\n *\n * Instead of storing each checkpoint in a separate storage slot, this library\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\n *\n * @dev Definitions:\n * - Checkpoint: A record of an APR change\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\n * - History: A dynamic array of packs\n * - Reference: A storage pointer to a checkpoint in the APR history\n * - CheckpointData: An in-memory representation of a checkpoint data\n *\n * @dev Value limitation:\n * This library can accommodate APRs only up to 65.536%. This is however sufficient for\n * APR in LToken contract, which is expected to remain below 10%.\n *\n * @dev For further details, see \"APRHistory\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary APRHistory {\n /**\n * @notice Represents data of a checkpoint extracted from the on-chain history.\n * For on-chain representation see \"Pack\" struct.\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\n * @param timestamp Timestamp of the checkpoint's creation.\n */\n struct CheckpointData {\n uint16 aprUD7x3; // Allows up to 65.536%\n uint40 timestamp; // Supports dates up to 20/02/36812\n }\n\n /**\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\n * @param aprsUD7x3 Array of checkpoints' APRs.\n * @param timestamps Array of checkpoints' timestamps.\n * @param cursor Index of the next checkpoint to be written.\n */\n struct Pack {\n uint16[4] aprsUD7x3;\n uint40[4] timestamps;\n uint32 cursor;\n }\n\n /**\n * @notice Represents a storage pointer to a specific checkpoint in the history.\n * @param packIndex Index of the pack the checkpoint belongs to.\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\n */\n struct Reference {\n uint256 packIndex;\n uint32 cursorIndex;\n }\n\n /**\n * @notice Compares two checkpoints references.\n * @param ref1 The first reference to compare.\n * @param ref2 The second reference to compare.\n * @return Whether the two references points to the same checkpoint.\n */\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\n }\n\n /**\n * @notice Returns the reference of the checkpoint that should come right after the\n * referenced checkpoint in the APR history.\n * @param ref The reference to be incremented.\n * @return The incremented reference.\n */\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L1\");\n\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\n //\n // Else, return ref of next slot in current pack\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\n }\n\n /**\n * @notice Extracts checkpoint data from a given reference and in APR history.\n * @param self The APR history to extract the checkpoint from.\n * @param ref The reference of the checkpoint data to extract.\n * @return The extracted checkpoint's data.\n */\n function getDataFromReference(\n Pack[] storage self,\n Reference memory ref\n ) public view returns (CheckpointData memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L2\");\n\n // Ensure pack index of the given ref exists in history\n require(ref.packIndex < self.length, \"L3\");\n\n // Retrieve pack data from history\n Pack memory pack = self[ref.packIndex];\n\n // Ensure cursor index of the given ref has been written\n require(ref.cursorIndex < pack.cursor, \"L4\");\n\n // Build and return the checkpoint data\n return\n CheckpointData({\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\n timestamp: pack.timestamps[ref.cursorIndex]\n });\n }\n\n /**\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\n * @param self The history to extract the reference from.\n * @return The reference of the latest checkpoint.\n */\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\n // Ensure the given history is not empty\n require(self.length != 0, \"L5\");\n\n // Retrieve latest pack's index and cursor\n uint256 packIndex = self.length - 1;\n uint32 packCursor = self[packIndex].cursor;\n\n // If this is the first pack ever, ensure it is not empty\n if (packIndex == 0) require(packCursor != 0, \"L6\");\n\n // If the pack is empty, return ref of previous pack's latest slot\n if (packCursor == 0) return Reference(packIndex - 1, 3);\n //\n // Else, return ref of previous slot in current pack\n else return Reference(packIndex, packCursor - 1);\n }\n\n /**\n * @notice Appends a new empty pack to the end of the given APR history array.\n * @param self The APR history to append an empty to.\n */\n function newBlankPack(Pack[] storage self) internal {\n // If history is not empty, ensure the latest pack is full\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \"L7\");\n\n // Push a new blank pack to the history array\n self.push(\n Pack({\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\n cursor: 0\n })\n );\n }\n\n /**\n * @notice Write a new APR checkpoint at the end of the given history array.\n * @param self The array of packs to write the new checkpoint to.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\n // Determine the reference where the new checkpoint should be written\n Reference memory newRef = self.length == 0\n ? Reference(0, 0)\n : incrementReference(getLatestReference(self));\n\n // If pack to be written doesn't exist yet, push a new blank pack in history\n if (newRef.packIndex >= self.length) newBlankPack(self);\n\n // Retrieve the pack where the new checkpoint will be stored\n Pack memory pack = self[newRef.packIndex];\n\n // Add new checkpoint's data to the pack\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\n\n // Increment the pack's cursor\n pack.cursor++;\n\n // Write the updated pack in storage\n self[newRef.packIndex] = pack;\n }\n\n /**\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\n * @param self The history array to read APR from.\n * @return The latest checkpoint's APR.\n */\n function getAPR(Pack[] storage self) public view returns (uint16) {\n // Retrieve the latest checkpoint data\n Reference memory ref = getLatestReference(self);\n CheckpointData memory data = getDataFromReference(self, ref);\n\n // Return the latest checkpoint's APR\n return data.aprUD7x3;\n }\n}\n" + }, + "contracts/src/libs/SUD.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title SUD\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice SUD serves as an intermediary number format for calculations within this\n * codebase. It ensures consistency and reduces precision losses. This library\n * facilitates conversions between various number formats and the SUD format.\n *\n * @dev Intuition:\n * This codebase employs the UD (unsigned decimal fixed-point numbers) format to\n * represent both percentage rates and tokens amounts.\n *\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\n * the decimals() value of the involved tokens.\n *\n * Three challenges arise from this:\n * 1) To compute values together, it's essential that they are in the same format\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\n * precision loss (because division shrinks). A common approach is to scale up and\n * down values by a few decimals before and after performing calculations.\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\n * be shrunk in case token's decimals number is in [0, 2].\n *\n * To address these challenges, this library provides the SUD format, which acts as a\n * consistent and scaled intermediate format to perform calculations.\n *\n * SUD is an acronym for either \"Scaled UD\" or \"Safe UD\".\n *\n * @dev Definitions:\n * - Integer: A number without fractional part, e.g., block.timestamp\n * - UD: A decimal unsigned fixed-point number. The \"UD\" notation is inspired from\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\n * - Amount: A token amount. A UD with an unknown repartition of digits between integral\n * and fractional parts (as token amounts have variable decimal numbers)\n * - Rate: A percentage rate. An UD with 7 integral digits and 3 fractional ones (= UD7x3)\n * - SUD: An intermediate format to perform calculations involving Rates and Amounts. A UD\n * with 3 more decimals than the involved UD with the highest decimals number. As\n * rates are represented by UD7x3, a SUD number has at least 6 decimals (3+3) and\n * so ranges from UD71x6 to UD0x77 formats.\n *\n * @dev A conversion library:\n * This library provides utilities to perform the following conversions:\n * - Amount <--> SUD\n * - Rate (UD7x3) <--> SUD\n * - Integer <--> SUD\n *\n * @dev Why scaling by 3 decimals?\n * - It provides an adequate degree of precision for this codebase,\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\n * the involved token's decimal number, so is gas efficient.\n *\n * @dev Why internal functions?\n * The functions of this library are not set to external because incorporating them\n * directly into contracts is more gas-efficient. Given their minimal size and frequent\n * usage in the InvestUpgradeable, LDYStaking, and LToken contracts, any bytecode savings\n * from making them external are negated by the additional bytecode required for external\n * calls to this library. This can be observed by comparing the output of `bun cc:size`\n * when those functions's visibility is set to external or internal.\n *\n * @dev Precision warning:\n * While this library mitigates precision loss during calculations on UD numbers, it's\n * important to note that tokens with lower decimal counts and supply inherently suffer\n * more from precision loss. Conversely, tokens with higher decimal counts and supply\n * will experience less precision loss.\n *\n * @dev For further details, see \"SUD\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary SUD {\n /**\n * @notice Retrieves decimals number of the given ERC20 contract address.\n * @param tokenAddress The address to retrieve decimals number from.\n * @return decimals The decimals number of the given ERC20 contract address.\n */\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\n }\n\n /**\n * @notice Convert a given token amount into SUD format.\n * @param nAmount The token amount to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The amount in SUD format\n */\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\n\n // Else return a number with decimals+3 fractional digits\n return nAmount * 10 ** 3;\n }\n\n /**\n * @notice Convert a given SUD number into token amount format.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nAmount The number in amount format\n */\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** 3;\n }\n\n /**\n * @notice Converts a given UD7x3 rate into SUD format.\n * @param nUD7x3 The UD7x3 rate to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The rate in SUD format.\n */\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nUD7x3 * 10 ** 3;\n\n // Else, return a number with decimals+3 fractional digits\n return nUD7x3 * 10 ** decimals;\n }\n\n /**\n * @notice Converts a given SUD number into a UD7x3 rate.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nUD7x3 The number in UD7x3 rate format.\n */\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 3;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** decimals;\n }\n\n /**\n * @notice Converts a given integer into SUD format.\n * @param n The integer to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The integer in SUD format.\n */\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return n * 10 ** 6;\n\n // Else, return a number with decimals+3 fractional digits\n return n * 10 ** (decimals + 3);\n }\n\n /**\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return n The SUD number as an integer.\n */\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 6;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** (decimals + 3);\n }\n}\n" + }, + "contracts/src/LToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport {ERC20WrapperUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\";\nimport \"./abstracts/base/ERC20BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"./abstracts/InvestUpgradeable.sol\";\nimport {LDYStaking} from \"./DummyLDYStaking.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {SUD} from \"./libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport {ITransfersListener} from \"./interfaces/ITransfersListener.sol\";\n\n/**\n * @title LToken\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e.,\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\n * the form of additional L-Tokens, which are auto-compounded over time.\n *\n * @dev Definitions:\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\n * - Instant: Processed immediately.\n * - Request: Queued for later processing.\n * - Big Request: A requested withdrawal exceeding half of the retention rate.\n * - (Withdrawal) queue: A list of all requested withdrawals sorted by priority.\n * - Request ID: The index of a withdrawal request in the queue array.\n * - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain.\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\n * expected ways and are so considered safe to use by the contract.\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\n * processing.\n *\n * Note that words between parenthesis are sometimes omitted for brevity.\n *\n * @dev Deployment notice:\n * This contract can safely receive funds immediately after initialization. (i.e., there\n * is no way for funds to be sent to non-owned addresses). It is, however, recommended to\n * replace ASAP owner and fund wallets with multi-sig wallets.\n *\n * @dev For further details, see \"LToken\" section of whitepaper.\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n * @custom:security-contact security@ledgity.com\n */\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @dev Represents type of actions triggering ActivityEvent events.\n enum Action {\n Deposit,\n Withdraw\n }\n\n /// @dev Represents different status of actions triggering ActivityEvent events.\n enum Status {\n Queued,\n Cancelled,\n Success,\n Moved\n }\n\n /**\n * @notice Represents a withdrawal request in the queue.\n * @dev A request fits in a single storage slot (32 bytes).\n * @param account The account that initiated the request.\n * @param amount The amount of underlying tokens requested.\n */\n struct WithdrawalRequest {\n address account; // 20 bytes\n uint96 amount; // 12 bytes\n }\n\n /// @notice Upper limit of retention rate.\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\n\n /// @notice Used in activity events to represent the absence of request ID.\n int256 private constant NO_ID = -1;\n\n /// @notice Holds a reference to the LDYStaking contract.\n LDYStaking public ldyStaking;\n\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\n address payable public withdrawer;\n\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\n address public fund;\n\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\n uint32 public feesRateUD7x3;\n\n /// @notice Holds the retention rate in UD7x3 format.\n uint32 public retentionRateUD7x3;\n\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\n uint256 public unclaimedFees;\n\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\n uint256 public totalQueued;\n\n /**\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\n */\n uint256 public usableUnderlyings;\n\n /// @notice Holds an ordered list of active withdrawal requests.\n WithdrawalRequest[] public withdrawalQueue;\n\n /// @notice Holds the index of the next withdrawal request to process in the queue.\n uint256 public withdrawalQueueCursor;\n\n /**\n * @notice Holds a list of all currently frozen withdrawal requests.\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\n * it from blocking the queue.\n */\n WithdrawalRequest[] public frozenRequests;\n\n /**\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\n */\n ITransfersListener[] public transfersListeners;\n\n /**\n * @notice Emitted to inform listeners about a change in the contract's TVL.\n * @dev TVL = realTotalSupply()\n * @param newTVL The new TVL of the contract.\n */\n event TVLChangeEvent(uint256 newTVL);\n\n /**\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\n * @param account The account involved in the activity.\n * @param action The type of activity.\n * @param amount The amount of underlying tokens involved in the activity.\n * @param newStatus The new status of the activity.\n * @param newId The new ID of the request if it has been moved in the queue.\n */\n event ActivityEvent(\n int256 indexed id,\n address indexed account,\n Action indexed action,\n uint256 amount,\n uint256 amountAfterFees,\n Status newStatus,\n int256 newId\n );\n\n /**\n * @notice Emitted to inform listeners that some rewards have been minted.\n * @param account The account that received the rewards.\n * @param balanceBefore The balance of the account before the minting.\n * @param rewards The amount of minted rewards.\n */\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\n\n /// @notice Reverts if the function caller is not the withdrawer wallet.\n modifier onlyWithdrawer() {\n require(_msgSender() == withdrawer, \"L39\");\n _;\n }\n\n /// @notice Reverts if the function caller is not the fund wallet.\n modifier onlyFund() {\n require(_msgSender() == fund, \"L40\");\n _;\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyStaking_,\n address underlyingToken\n ) public initializer {\n // Initialize ERC20 base.\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\n __ERC20Base_init(\n globalOwner_,\n globalPause_,\n globalBlacklist_,\n string(abi.encodePacked(\"Ledgity \", underlyingSymbol)),\n string(abi.encodePacked(\"L\", underlyingSymbol))\n );\n\n // IMPORTANT: Below calls must not be restricted to owner at any point.\n // This is because the GlobalOwner contract may not be a fresh one, and so\n // the contract deployer may not be the owner anymore after ERC20Base init.\n\n // Initialize other parents contracts.\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\n __Invest_init_unchained(address(this));\n\n // Set LDYStaking contract\n ldyStaking = LDYStaking(ldyStaking_);\n\n // Set initial withdrawal fees rate to 0.3%\n feesRateUD7x3 = 300;\n\n // Set initial retention rate to 10%\n retentionRateUD7x3 = 10_000;\n\n // Default withdrawer and fund wallet to contract owner address. This prevents\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\n withdrawer = payable(owner());\n fund = payable(owner());\n }\n\n /**\n * @notice Required override of decimals() which is implemented by both\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\n * decimals amount of the underlying stablecoin token.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function decimals()\n public\n view\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\n returns (uint8)\n {\n return ERC20WrapperUpgradeable.decimals();\n }\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @notice Updates the current withdrawal fee rate.\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\n */\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\n feesRateUD7x3 = feesRateUD7x3_;\n }\n\n /**\n * @notice Updates the current underlying token retention rate.\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\n * deposited assets will ever be exposed in this contract (reduces attack surface).\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\n */\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \"L41\");\n retentionRateUD7x3 = retentionRateUD7x3_;\n }\n\n /**\n * @notice Updates the address of LDYStaking contract.\n * @param ldyStakingAddress The address of the new LDYStaking contract.\n */\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\n ldyStaking = LDYStaking(ldyStakingAddress);\n }\n\n /**\n * @notice Updates the address of the withdrawer wallet.\n * @param withdrawer_ The address of the new withdrawer wallet.\n */\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\n // Ensure address is not the zero address (pre-processing fees would be lost else)\n require(withdrawer_ != address(0), \"L63\");\n\n // Set new withdrawer wallet's address\n withdrawer = withdrawer_;\n }\n\n /**\n * @notice Updates the address of the fund wallet.\n * @param fund_ The address of the new fund wallet.\n */\n function setFund(address payable fund_) public onlyOwner {\n // Ensure address is not the zero address (deposited tokens would be lost else)\n require(fund_ != address(0), \"L64\");\n\n // Set new fund wallet's address\n fund = fund_;\n }\n\n /**\n * @notice Adds a new contract to the L-Token transfers list.\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\n * specified contract will be called.\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\n * contracts that are not owned by the Ledgity team.\n * @param listenerContract The address of the new transfers listener contract.\n */\n function listenToTransfers(address listenerContract) public onlyOwner {\n transfersListeners.push(ITransfersListener(listenerContract));\n }\n\n /**\n * @notice Removes a contract from the L-Token transfers list.\n * @dev The onLTokenTransfer() function of the specified contract will not be called\n * anymore each time a L-Token transfer occurs.\n * @param listenerContract The address of the listener contract.\n */\n function unlistenToTransfers(address listenerContract) public onlyOwner {\n // Find index of listener contract in transferListeners array\n int256 index = -1;\n uint256 transfersListenersLength = transfersListeners.length;\n for (uint256 i = 0; i < transfersListenersLength; i++) {\n if (address(transfersListeners[i]) == listenerContract) {\n index = int256(i);\n break;\n }\n }\n\n // Revert if given contract wasn't listening to transfers\n require(index > -1, \"L42\");\n\n // Else, remove transfers listener contract from listeners array\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\n transfersListeners.pop();\n }\n\n /**\n * @notice Retrieves the amount of given account's not yet minted rewards.\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\n * context of LToken, this function returns the amount of rewards that have not been\n * distributed/minted yet to the specified account.\n * @dev This is particularly useful for off-chain services to display charts and\n * statistics, as seen in the Ledgity Yield's frontend.\n * @param account The account to check the unminted rewards of.\n * @return The amount of account's unminted rewards.\n */\n function unmintedRewardsOf(address account) public view returns (uint256) {\n return _rewardsOf(account, true);\n }\n\n /**\n * @notice Retrieves the \"real\" balance of an account, i.e., excluding its not yet\n * minted/distributed rewards.\n * @param account The account to check the real balance of.\n * @return The real balance of the account.\n */\n function realBalanceOf(address account) public view returns (uint256) {\n return super.balanceOf(account);\n }\n\n /**\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\n * not been yet minted to the specified account.\n * @param account The account to check the total balance of.\n * @return The total balance of the account.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return realBalanceOf(account) + unmintedRewardsOf(account);\n }\n\n /**\n * @notice Returns the \"real\" amount of existing L-Tokens, i.e., excluding not yet\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\n * @return The real total supply of L-Tokens.\n */\n function realTotalSupply() public view returns (uint256) {\n return super.totalSupply();\n }\n\n /**\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\n * fees and L-Tokens currently in the withdrawal queue.\n * @return The total supply of L-Tokens.\n */\n function totalSupply() public view override returns (uint256) {\n return realTotalSupply() + totalQueued + unclaimedFees;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address.\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\n * token from being the underlying token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the underlying token\n require(tokenAddress != address(underlying()), \"L43\");\n\n // Proceed to recovery\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @notice Recovers underlying tokens accidentally sent to the contract.\n * @dev To prevent owner from being able to drain the contract, this function only\n * allows recovering \"unusable\" underlying tokens, i.e., tokens that have not been\n * sent through fund() or deposit() functions.\n */\n function recoverUnderlying() external onlyOwner {\n // Compute the recoverable amount by taking the difference between the contract's\n // balance and the amount of usable underlying tokens\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\n\n // Revert if there is nothing to recover\n require(recoverableAmount > 0, \"L44\");\n\n // Else, proceed to underlying tokens recovery\n super.recoverERC20(address(underlying()), recoverableAmount);\n }\n\n /**\n * @notice Retrieves the amount of underlying tokens invested by the given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\n * LToken contract, the investment of an account is equal to its real balance.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return realBalanceOf(account);\n }\n\n /**\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract so\n * it can distribute rewards to accounts before each period reset.\n * @dev InvestUpgradeable contract already ensure that amount > 0.\n * @inheritdoc InvestUpgradeable\n */\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\n // Inform listeners of the rewards minting\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\n\n // Mint L-Tokens rewards to account\n _mint(account, amount);\n\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\n return true;\n }\n\n /**\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\n * called each time an account's balance is going to change.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\n * @inheritdoc ERC20BaseUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\n\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\n if (from != address(0)) _beforeInvestmentChange(from, true);\n if (to != address(0)) _beforeInvestmentChange(to, true);\n }\n\n /**\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\n * transfers listeners.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already checked in _beforeTokenTransfer().\n * @inheritdoc ERC20Upgradeable\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\n super._afterTokenTransfer(from, to, amount);\n\n // If some L-Token have been burned/minted, inform listeners of a TVL change\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\n\n // Trigger onLTokenTransfer() functions of all the transfers listeners\n for (uint256 i = 0; i < transfersListeners.length; i++) {\n transfersListeners[i].onLTokenTransfer(from, to, amount);\n }\n }\n\n /**\n * @notice Computes the maximum amount of underlying tokens that should be retained\n * by the contract (based on retention rate).\n * @return amount The expected amount of retained underlying tokens.\n */\n function getExpectedRetained() public view returns (uint256 amount) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert totalSupply and retentionRate to SUD\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\n\n // Compute and return expected retained amount\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(expectedRetainedSUD, d);\n }\n\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\n function _transferExceedingToFund() internal {\n // Retrieve the expected amount retained\n uint256 expectedRetained = getExpectedRetained();\n\n // If usable underlyings are less than or equal to expected retained, return\n if (usableUnderlyings <= expectedRetained) return;\n\n // Else, exceeding amount is equal to difference between those values\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= exceedingAmount;\n\n // Transfer the exceeding amount to the fund wallet\n underlying().safeTransfer(fund, exceedingAmount);\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L45\");\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\n * Use deposit() function instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L46\");\n }\n\n /**\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\n * @param amount The amount of underlying tokens to deposit.\n */\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough underlying tokens to deposit\n require(underlying().balanceOf(_msgSender()) >= amount, \"L47\");\n\n // Update usable underlyings balance accordingly\n usableUnderlyings += amount;\n\n // Inform listeners of the deposit activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Deposit,\n amount,\n amount,\n Status.Success,\n NO_ID\n );\n\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\n super.depositFor(_msgSender(), amount);\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\n * given amount.\n * @param account The account initiating the withdrawal.\n * @param amount The amount of the withdrawal.\n */\n function getWithdrawnAmountAndFees(\n address account,\n uint256 amount\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\n // If the account is eligible to staking tier 2, no fees are applied\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\n\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert amount and fees rate to SUD\n uint256 amountSUD = SUD.fromAmount(amount, d);\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\n\n // Compute fees and withdrawn amount (initial amount minus fees)\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\n fees = SUD.toAmount(feesSUD, d);\n withdrawnAmount = amount - fees;\n }\n\n /**\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\n * enough underlying tokens to cover the withdrawal.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestWithdrawal() function otherwise.\n * @param amount The amount L-Tokens to withdraw.\n */\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L48\");\n\n // Can the contract cover this withdrawal plus all already queued requests?\n bool cond1 = totalQueued + amount <= usableUnderlyings;\n\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\n\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\n if (!(cond1 || cond2)) revert(\"L49\");\n\n // Else, retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\n\n // Increase unclaimed fees amount accordingly\n unclaimedFees += fees;\n\n // Decrease usable underlyings balance accordingly\n usableUnderlyings -= withdrawnAmount;\n\n // Inform listeners of this instant withdrawal activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Withdraw,\n amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Burn withdrawal fees from the account\n _burn(_msgSender(), fees);\n\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\n super.withdrawTo(_msgSender(), withdrawnAmount);\n }\n\n /**\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\n * amount of underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n * @param amount The amount L-Tokens to withdraw.\n */\n function requestWithdrawal(\n uint256 amount\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L53\");\n\n // Ensure the requested amount doesn't overflow uint96\n require(amount <= type(uint96).max, \"L54\");\n\n // Ensure the sender attached the pre-paid processing gas fees\n require(msg.value == 0.003 * 10 ** 18, \"L55\");\n\n // Create withdrawal request data\n WithdrawalRequest memory request = WithdrawalRequest({\n account: _msgSender(),\n amount: uint96(amount)\n });\n\n // Will hold the request ID\n uint256 requestId;\n\n // Append request to the withdrawal queue:\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\n withdrawalQueueCursor--;\n requestId = withdrawalQueueCursor;\n withdrawalQueue[requestId] = request;\n }\n // - At the end else\n else {\n withdrawalQueue.push(request);\n requestId = withdrawalQueue.length - 1;\n }\n\n // Increase total amount queued accordingly\n totalQueued += amount;\n\n // Inform listeners of this new queued withdrawal activity event\n emit ActivityEvent(\n int256(requestId),\n _msgSender(),\n Action.Withdraw,\n amount,\n amount,\n Status.Queued,\n NO_ID\n );\n\n // Burn withdrawal L-Tokens amount from account's balance\n _burn(_msgSender(), amount);\n\n // Forward pre-paid processing gas fees to the withdrawer wallet\n (bool sent, ) = withdrawer.call{value: msg.value}(\"\");\n require(sent, \"L56\");\n }\n\n /**\n * @notice Processes queued withdrawal requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n * @dev For further details, see \"LToken > Withdrawals\" section of whitepaper.\n */\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\n // Accumulators variables, will be written on-chain after the loop\n uint256 cumulatedFees = 0;\n uint256 cumulatedWithdrawnAmount = 0;\n uint256 nextRequestId = withdrawalQueueCursor;\n\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\n // requests are increasing the queue length when moved at the end of the queue.\n uint256 queueLength = withdrawalQueue.length;\n\n // Iterate over requests to be processed\n while (nextRequestId < queueLength) {\n // Stop processing requests if there is not enough gas left to continue the\n // loop and properly end the function call. This prevents an attacker from\n // blocking the withdrawal processing by creating a ton of tiny requests so\n // this function call cannot fit anymore in block gas limit.\n if (gasleft() < 45000) break;\n\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\n\n // Skip empty request (processed big requests or cancelled requests)\n if (request.account == address(0)) {}\n //\n // If account has been blacklisted since request emission\n else if (isBlacklisted(request.account)) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request in the frozen requests list\n frozenRequests.push(request);\n }\n //\n // Or if request is a big request, move it at the end of the queue for now.\n // This request will be processed manually later using processBigQueuedRequest()\n else if (request.amount > getExpectedRetained() / 2) {\n // Inform listeners of this queued request being moved at the end of the queue\n emit ActivityEvent(\n int256(nextRequestId),\n _msgSender(),\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Moved,\n int256(withdrawalQueue.length)\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request at the end of the queue\n withdrawalQueue.push(request);\n }\n //\n // Else, continue request processing\n else {\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Break if the contract doesn't hold enough funds to cover the request\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\n\n // Accumulate fees and withdrawn amount\n cumulatedFees += fees;\n cumulatedWithdrawnAmount += withdrawnAmount;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(nextRequestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Transfer underlying tokens to account. Burning L-Tokens is not required\n // as equestWithdrawal() already did it.\n // Security note: Re-entrancy warning are disabled as the request has\n // just been deleted from the queue, it will so be skipped if trying to\n // process it again.\n // slither-disable-next-line reentrancy-no-eth\n underlying().safeTransfer(request.account, withdrawnAmount);\n }\n\n // Increment next request ID\n nextRequestId++;\n }\n\n // Increase unclaimed fees by the amount of cumulated fees\n unclaimedFees += cumulatedFees;\n\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\n usableUnderlyings -= cumulatedWithdrawnAmount;\n\n // Decrease total amount queued by the cumulated amount requested\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\n\n // Update new queue cursor\n withdrawalQueueCursor = nextRequestId;\n\n // Retention rate cannot exceeds as the withdrawal decreases both usable\n // underlyings and expected retained amounts by the same number and as the\n // expected retained amount is a subset of usable underlyings amount.\n }\n\n /**\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\n * the retention rate).\n * @dev In contrast to non-big requests processing, this function will uses to fund\n * wallet's balance to fill the request. This allows processing requests that are\n * greater than retention rate without having to exceed this rate on the contract.\n * @param requestId The ID of the big request to process.\n */\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure the request is active\n require(request.account != address(0), \"L66\");\n\n // Ensure the request emitter has not been blacklisted since request emission\n require(!isBlacklisted(request.account), \"L50\");\n\n // Ensure this is indeed a big request\n require(request.amount > getExpectedRetained() / 2, \"L51\");\n\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\n uint256 fundBalance = underlying().balanceOf(fund);\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \"L52\");\n\n // Increase amount of unclaimed fees accordingly\n unclaimedFees += fees;\n\n // Decrease total queued amount by request amount\n totalQueued -= request.amount;\n\n // Increment queue cursor if request was the next request to be processed\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[requestId];\n\n // If fund wallet's balance can cover request, rely on it only\n if (withdrawnAmount <= fundBalance) {\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\n }\n // Else, cover request from both fund wallet and contract balances\n else {\n // Compute amount missing from fund wallet to cover request\n uint256 missingAmount = withdrawnAmount - fundBalance;\n\n // Decrease usable amount of underlying tokens accordingly\n usableUnderlyings -= missingAmount;\n\n // Transfer entire fund balance to request's emitter\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\n\n // Transfer missing amount from contract balance to request emitter\n underlying().safeTransfer(request.account, missingAmount);\n }\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Cancels a given withdrawal request. The request emitter receive back its\n * L-Tokens and no fees will be charged.\n * @param requestId The ID of the withdrawal request to cancel.\n */\n function cancelWithdrawalRequest(\n uint256 requestId\n ) public whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure request belongs to caller\n require(_msgSender() == request.account, \"L57\");\n\n // Decrease total amount queued accordingly\n totalQueued -= request.amount;\n\n // Delete the withdrawal request from queue\n delete withdrawalQueue[requestId];\n\n // Inform listeners of this cancelled withdrawal request activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Cancelled,\n NO_ID\n );\n\n // Mint back L-Tokens to account\n _mint(request.account, uint256(request.amount));\n }\n\n /**\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\n * whenever those are required to fulfill some withdrawal requests.\n * @dev The function will revert if repatriated amount makes the contract exceeding\n * the retention rate.\n * @param amount The amount of underlying tokens to repatriate.\n */\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\n // Ensure the fund wallet has enough funds to repatriate\n require(amount <= underlying().balanceOf(fund), \"L58\");\n\n // Calculate new contract usable balance\n uint256 newBalance = usableUnderlyings + amount;\n\n // Ensure the new balance doesn't exceed the retention rate\n require(newBalance <= getExpectedRetained(), \"L59\");\n\n // Increase usable underlyings amount by repatriated amount\n usableUnderlyings += amount;\n\n // Transfer amount from fund wallet to contract\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /// @notice Used by owner to claim fees generated from successful withdrawals.\n function claimFees() external onlyOwner {\n // Ensure there are some fees to claim\n require(unclaimedFees > 0, \"L60\");\n\n // Ensure the contract holds enough underlying tokens to cover fees\n require(usableUnderlyings >= unclaimedFees, \"L61\");\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= unclaimedFees;\n\n // Store fees amount in memory and reset unclaimed fees amount\n uint256 fees = unclaimedFees;\n unclaimedFees = 0;\n\n // Transfer unclaimed fees to owner\n underlying().safeTransfer(owner(), fees);\n }\n}\n" + }, + "contracts/src/LTokenSignaler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title LTokenSignaler\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Used to inform subgraph from the existence of a new L-Token contract. Once\n * signaled, a L-Token will start being indexed.\n *\n * @dev Signal are ignored by the subgraph if the L-Token is already known by it.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LTokenSignaler is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Emitted to inform subgraph of the existence of a new L-Token contract.\n * @param lTokenAddress The address of the L-Token contract to signal.\n */\n event LTokenSignalEvent(address indexed lTokenAddress);\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Signals a LToken contract to the TheGraph subgraph of the current chain.\n * @param lTokenAddress The address of the LToken contract to signal.\n */\n function signalLToken(address lTokenAddress) external onlyOwner {\n // Signal the LToken contract\n emit LTokenSignalEvent(lTokenAddress);\n }\n}\n" + }, + "contracts/src/PreMining.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {LToken} from \"./LToken.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\n/**\n * @title PreMining\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n\n * @notice PreMining pool contract, allowing accounts to lock underlying tokens in a \n * pre-defined L-Token contract, over a given duration (in months), in exchange of \n * vested LDY rewards.\n * \n * @dev Intuition\n * \n * Lifecycle of a lockdrop pool is composed by 3 main phases:\n * 1) Deposit: During this phase, users can lock their underlying tokens.\n * 2) Claim: During this phase, users can claim their LDY rewards.\n * 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract.\n * \n * Transitioning between two phases is manually triggered by contract's owner.\n * To ensure fair usage of this power and prevent potential misuse:\n * - the Recovery phase cannot start before 3 months after the end of rewards vesting,\n * - the Recovery phase cannot start before 3 months after the maximum lock end.\n * \n * Finally, note that this contract proxies main L-Token contract's functions:\n * - lock() --> deposit()\n * - instantUnlock() --> instantWithdrawal()\n * - requestUnlock() --> requestWithdrawal()\n * This design enables users to interact with the PreMining contract in a similar fashion\n * to the L-Token contract.\n * \n * @dev Definitions:\n * - Locker: An account that has locked underlying tokens in the pool.\n * \n * @custom:security-contact security@ledgity.com\n */\ncontract PreMining is Ownable2Step, Pausable {\n using SafeERC20 for IERC20;\n\n /**\n * @notice Represents the lock information of an account.\n * @param amount Amount of underlying tokens locked.\n * @param duration Duration of the lock (in months).\n * @param hasUnlocked Whether the account has unlocked its locked tokens.\n * @param claimedRewards Amount of LDY rewards already claimed.\n * @param lockEndTimestamp Timestamp at which the account's lock ends.\n */\n struct AccountLock {\n uint240 amount;\n uint8 duration;\n bool hasUnlocked;\n uint216 claimedRewards;\n uint40 lockEndTimestamp;\n }\n\n /// @notice Holds the amount of LDY to be distributed to lockers.\n uint256 public immutable maxDistributedLDY;\n\n /// @notice Holds the maximum total amount of L-Tokens that can be locked.\n uint256 public immutable lockedHardCap;\n\n /// @notice Holds the minimum possible lock duration (in months).\n uint8 public immutable minLockDuration;\n\n /// @notice Holds the maximum possible lock duration (in months).\n uint8 public immutable maxLockDuration;\n\n /// @notice Holds the duration of LDY rewards vesting (in months).\n uint8 public immutable vestingDuration;\n\n /// @notice Holds a reference to the locked L-Token contract.\n LToken public immutable lToken;\n\n /// @notice Holds a reference to the L-Token underlying stablecoin.\n IERC20 public immutable underlyingToken;\n\n /// @notice Holds the max pool weight.\n uint256 public immutable maxWeight;\n\n /// @notice Holds a reference to the LDY token contract.\n IERC20 public ldyToken;\n\n /// @notice Holds lockers' participations informations.\n mapping(address => AccountLock) public accountsLocks;\n\n /// @notice Holds the total amount of locked underlying tokens.\n uint256 public totalLocked;\n\n /// @notice Holds whether the Deposit phase has ended.\n bool public hasDepositPhaseEnded;\n\n /// @notice Holds whether the Claim phase has started.\n bool public hasClaimPhaseStarted;\n\n /// @notice Holds whether the Recovery phase has started.\n bool public hasRecoveryPhaseStarted;\n\n /// @notice Holds the timestamp at which the Claim phase started.\n uint256 public claimPhaseStartTimestamp;\n\n /// @notice Holds an ordered queue of accounts that requested to unlock their tokens.\n address[] public unlockRequests;\n\n /// @notice Holds the index of the first request in the queue (a.k.a, next one to be processed).\n uint256 public unlockRequestsCursor;\n\n /// @notice Emitted to inform about a new lock/deposit.\n event Lock(address indexed account, uint256 amount, uint8 duration);\n\n /// @notice Top-level checks and code shared by both unlock functions.\n modifier safeUnlock() {\n // Ensure that the account's lock has ended\n require(accountsLocks[msg.sender].lockEndTimestamp <= block.timestamp, \"L68\");\n\n // Ensure the account hasn't already unlocked its tokens\n require(!accountsLocks[msg.sender].hasUnlocked, \"L69\");\n\n // Ensure the account has something to unlock\n require(accountsLocks[msg.sender].amount > 0, \"L70\");\n\n // Indicate that account has unlocked its tokens\n accountsLocks[msg.sender].hasUnlocked = true;\n _;\n }\n\n /**\n * @notice This constructor function etches the lockdrop terms in immutable states.\n * Ensuring that those terms cannot be modified after deployment.\n * @param lTokenAddress_ Address of the L-Token contract to use.\n * @param maxDistributedLDY_ Amount of LDY to be distributed to lockers.\n * @param lockedHardCap_ Maximum total amount of L-Tokens that can be locked.\n * @param minLockDuration_ Minimum possible lock duration (in months).\n * @param maxLockDuration_ Maximum possible lock duration (in months).\n * @param vestingDuration_ Duration of LDY rewards vesting (in months).\n */\n constructor(\n address lTokenAddress_,\n uint256 maxDistributedLDY_,\n uint256 lockedHardCap_,\n uint8 minLockDuration_,\n uint8 maxLockDuration_,\n uint8 vestingDuration_\n ) {\n // Ensure minLockDuration is at least 1 month\n require(minLockDuration_ >= 1, \"L72\");\n\n // Ensure minLockDuration is not greater than maxLockDuration\n require(minLockDuration_ <= maxLockDuration_, \"L73\");\n\n // Set immutable states\n lToken = LToken(lTokenAddress_);\n underlyingToken = IERC20(address(lToken.underlying()));\n lockedHardCap = lockedHardCap_;\n maxDistributedLDY = maxDistributedLDY_;\n minLockDuration = minLockDuration_;\n maxLockDuration = maxLockDuration_;\n vestingDuration = vestingDuration_;\n maxWeight = lockedHardCap * uint256(maxLockDuration);\n }\n\n /**\n * @notice Public implementation of Pausable's pausing and unpausing functions, but\n * restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Updates the LDY token contract address.\n * @dev As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE,\n * this function allows the contract's owner to set the LDY token address once it\n * becomes available.\n * @param ldyTokenAddress Address of the LDY token contract.\n */\n function setLDYToken(address ldyTokenAddress) external onlyOwner {\n // Prevent owner from changing the LDY address after Claim phase has started\n require(!hasClaimPhaseStarted, \"L74\");\n\n // Set LDY token address\n ldyToken = IERC20(ldyTokenAddress);\n }\n\n /**\n * @notice Closes the Deposit phase. After calling this function, account won't be\n * able to lock additional underlying tokens anymore.\n */\n function endDepositPhase() external onlyOwner {\n hasDepositPhaseEnded = true;\n }\n\n /**\n * @notice Opens the Claim phase. After calling this function, lockers will be able\n * to start claiming their LDY rewards.\n */\n function startClaimPhase() external onlyOwner {\n // Ensure Claim phase has not already started\n require(!hasClaimPhaseStarted, \"L76\");\n\n // Ensure that LDY token address is available\n require(address(ldyToken) != address(0), \"L77\");\n\n // Set Claim phase as started and store the start timestamp\n hasClaimPhaseStarted = true;\n claimPhaseStartTimestamp = block.timestamp;\n }\n\n /**\n * @notice Opens the Recovery phase. After calling this function, the contract owner\n * will be able to recover remaining ERC20 tokens on the contract.\n * Note that this won't close the Claim phase and lockers will still be able to claim\n * their LDY rewards.\n */\n function startRecoveryPhase() external onlyOwner {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L79\");\n\n // Compute some durations in seconds\n uint256 threeMonthsInSecond = 3 * 30 days;\n uint256 vestingInSecond = uint256(vestingDuration) * 30 days;\n uint256 maxLockInSecond = uint256(maxLockDuration) * 30 days;\n\n // Compute timestamp of vesting end + 3 months\n uint256 afterVestingTimestamp = claimPhaseStartTimestamp +\n vestingInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the end of reward vesting\n // This prevents owner from recovering LDY before lockers can claim their rewards\n require(block.timestamp >= afterVestingTimestamp, \"L80\");\n\n // Compute end of maximum lock + 3 months\n // Note that claimPhaseStartTimestamp is used for simplicity even if it can exist a time\n // span between Deposit and Claim phases.\n uint256 afterMaxLockTimestamp = claimPhaseStartTimestamp +\n maxLockInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the maximum lock end\n // This prevents owner from recovering underlying tokens before lockers can unlock those\n require(block.timestamp >= afterMaxLockTimestamp, \"L81\");\n\n // Set recovery phase as started\n hasRecoveryPhaseStarted = true;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address. Will revert if\n * recovery phase has not started yet or if the contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\n // Ensure recovery phase has started\n require(hasRecoveryPhaseStarted, \"L82\");\n\n // Create a reference to token's contract\n IERC20 tokenContract = IERC20(tokenAddress);\n\n // Ensure there is enough tokens to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L83\");\n\n // Transfer the recovered token amount to the sender (owner)\n tokenContract.safeTransfer(msg.sender, amount);\n }\n\n /**\n * @notice Compute the total amount of LDY rewards that a given account is eligible to.\n * @dev Note: This function neither considers vesting nor already claimed rewards.\n * @param account The account to compute the eligible rewards of.\n * @return The total amount of LDY rewards that the account is eligible to.\n */\n function eligibleRewardsOf(address account) public view returns (uint256) {\n // Compute account's lock weight\n uint256 lockerWeight = accountsLocks[account].amount * accountsLocks[account].duration;\n\n // Compute amount of LDY that this locker is eligible to\n if (maxWeight == 0) return 0;\n else return (maxDistributedLDY * lockerWeight) / maxWeight;\n }\n\n /**\n * @notice Allows locking a specified amount of underlying tokens for a given duration.\n * By locking, an account became eligible to a portion of the distributed LDY rewards.\n * @dev This function proxies LToken.deposit()\n * @dev Lockers can extend their lock duration by calling this function again with a\n * greater duration and 0 as amount.\n * @param amount Amount of underlying tokens to lock.\n * @param duration Duration of the lock (in months).\n */\n function lock(uint256 amount, uint8 duration) external whenNotPaused {\n // Ensure Deposit phase has not ended yet\n require(!hasDepositPhaseEnded, \"L84\");\n\n // Ensure account hasn't already unlocked a past lock\n require(!accountsLocks[msg.sender].hasUnlocked, \"L71\");\n\n // Ensure lock duration is in valid range\n require(duration >= minLockDuration && duration <= maxLockDuration, \"L85\");\n\n // Ensure it won't exceed the hardcap\n require(totalLocked + amount <= uint256(lockedHardCap), \"L86\");\n\n // Increase account's locked amount\n accountsLocks[msg.sender].amount += uint240(amount);\n\n // Increase total locked amount accordingly\n totalLocked += amount;\n\n // Use existing lock duration if greater than the new one\n uint8 existingDuration = accountsLocks[msg.sender].duration;\n uint8 appliedDuration = existingDuration > duration ? existingDuration : duration;\n\n // Update account's lock duration\n accountsLocks[msg.sender].duration = appliedDuration;\n\n // Update account's lock end timestamp\n accountsLocks[msg.sender].lockEndTimestamp = uint40(\n block.timestamp + uint40(appliedDuration) * 30 days\n );\n\n // Emit a Lock event\n emit Lock(msg.sender, amount, appliedDuration);\n\n // If amount is 0, skip deposit\n if (amount == 0) return;\n\n // Transfer underlyingToken from account to contract\n underlyingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n // Deposit USDC in the L-Token contract\n underlyingToken.safeApprove(address(lToken), amount);\n lToken.deposit(amount);\n }\n\n /**\n * @notice Allows the caller to instaneously unlock its locked amount of underlying\n * tokens.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestUnlock() function otherwise.\n */\n function instantUnlock() external whenNotPaused safeUnlock {\n // Retrieve underlying tokens from the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.instantWithdrawal(unlockedAmount);\n\n // Transfer underlying tokens back to caller\n underlyingToken.safeTransfer(msg.sender, unlockedAmount);\n }\n\n /**\n * @notice Allows the call to request for the unlocking of its locked amount of\n * underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n */\n function requestUnlock() external payable whenNotPaused safeUnlock {\n // Put account in the unlock requests queue\n unlockRequests.push(msg.sender);\n\n // Request underlying tokens to the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.requestWithdrawal{value: msg.value}(unlockedAmount);\n }\n\n /**\n * @notice Processes queued unlock requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n */\n function processUnlockRequests() external onlyOwner {\n // Store the current request ID to process\n uint256 processedId = unlockRequestsCursor;\n\n // Loop over remaining requests\n while (processedId < unlockRequests.length) {\n // Prevent OOG by stopping request processing if there is not enough gas left\n // to continue the loop and properly end the function call.\n if (gasleft() < 45000) break;\n\n // Retrieve the request account\n address unlockAccount = unlockRequests[processedId];\n\n // Retrieve the unlocked amount\n uint256 unlockAmount = accountsLocks[unlockAccount].amount;\n\n // If the request has already been processed, skip it\n if (unlockAccount != address(0)) {\n // If the contract doesn't hold enough underlying tokens to process the request, stop here\n if (underlyingToken.balanceOf(address(this)) < unlockAmount) break;\n\n // Delete the request\n delete unlockRequests[processedId];\n\n // Transfer underlying back to account\n underlyingToken.safeTransfer(unlockAccount, unlockAmount);\n }\n\n // Increment processed request ID\n processedId++;\n }\n\n // Write back the cursor in storage\n unlockRequestsCursor = processedId;\n }\n\n /**\n * @notice Computes the amount of LDY rewards available to claim for a given account.\n * @dev This function considers vesting and already claimed rewards.\n * @param account The account to compute the available rewards of.\n * @return The amount of LDY rewards available to claim.\n */\n function availableToClaim(address account) public view returns (uint256) {\n // Compute total amount of rewards allocated to this locker\n uint256 totalEligibleRewards = eligibleRewardsOf(account);\n\n // Compute vesting duration in seconds\n uint256 vestingInSeconds = uint256(vestingDuration) * 30 days;\n\n // Compute elapsed months since claim phase started, and cap it to vesting duration\n uint256 elapsedTime = block.timestamp - claimPhaseStartTimestamp;\n if (elapsedTime > vestingInSeconds) elapsedTime = vestingInSeconds;\n\n // Compute total available to claim (proportionally to elapsed time)\n uint256 totalAvailableToClaim = (totalEligibleRewards * elapsedTime) / vestingInSeconds;\n\n // Else return net claimable (available minus already claimed)\n return totalAvailableToClaim - accountsLocks[account].claimedRewards;\n }\n\n /// @notice Allows the caller to claim its available LDY rewards.\n function claimRewards() external whenNotPaused {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L87\");\n\n // Compute claimable LDY rewards\n uint256 claimableLDY = availableToClaim(msg.sender);\n\n // Increase account claimed amount accordingly\n accountsLocks[msg.sender].claimedRewards += uint216(claimableLDY);\n\n // Transfer rewards to account\n ldyToken.safeTransfer(msg.sender, claimableLDY);\n }\n}\n" + } + }, + "settings": { + "evmVersion": "london", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/contracts/hardhat/deployments/localhost/solcInputs/51ee222fb2f1beb1ef1977fa0bb4b538.json b/contracts/hardhat/deployments/localhost/solcInputs/51ee222fb2f1beb1ef1977fa0bb4b538.json deleted file mode 100644 index d532c437..00000000 --- a/contracts/hardhat/deployments/localhost/solcInputs/51ee222fb2f1beb1ef1977fa0bb4b538.json +++ /dev/null @@ -1,184 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeTo(address newImplementation) public virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../security/PausableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract unpausable.\n */\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\n function __ERC20Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../utils/SafeERC20Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the ERC20 token contract to support token wrapping.\n *\n * Users can deposit and withdraw \"underlying tokens\" and receive a matching number of \"wrapped tokens\". This is useful\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\n * wrapping of an existing \"basic\" ERC20 into a governance token.\n *\n * _Available since v4.2._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\n IERC20Upgradeable private _underlying;\n\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n __ERC20Wrapper_init_unchained(underlyingToken);\n }\n\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n require(underlyingToken != this, \"ERC20Wrapper: cannot self wrap\");\n _underlying = underlyingToken;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n */\n function decimals() public view virtual override returns (uint8) {\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\n return value;\n } catch {\n return super.decimals();\n }\n }\n\n /**\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\n */\n function underlying() public view returns (IERC20Upgradeable) {\n return _underlying;\n }\n\n /**\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\n */\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\n address sender = _msgSender();\n require(sender != address(this), \"ERC20Wrapper: wrapper can't deposit\");\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" - }, - "@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "@openzeppelin/contracts/access/Ownable2Step.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" - }, - "@openzeppelin/contracts/security/Pausable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n /**\n * @dev Destroys `amount` tokens from the caller.\n *\n * See {ERC20-_burn}.\n */\n function burn(uint256 amount) public virtual {\n _burn(_msgSender(), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n * allowance.\n *\n * See {ERC20-_burn} and {ERC20-allowance}.\n *\n * Requirements:\n *\n * - the caller must have allowance for ``accounts``'s tokens of at least\n * `amount`.\n */\n function burnFrom(address account, uint256 amount) public virtual {\n _spendAllowance(account, _msgSender(), amount);\n _burn(account, amount);\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "contracts/src/abstracts/base/BaseUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"../GlobalOwnableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"../GlobalRestrictableUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../RecoverableUpgradeable.sol\";\n\n/**\n * @title BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract acts as a base for numerous contracts contract in this\n * codebase, minimizing code repetition and enhancing readability and maintainability.\n *\n * @dev For further details, see \"Base\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract BaseUpgradeable is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n GlobalPausableUpgradeable,\n GlobalRestrictableUpgradeable,\n RecoverableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_\n ) internal onlyInitializing {\n __UUPSUpgradeable_init();\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n __Recoverable_init_unchained();\n }\n\n function __Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/base/ERC20BaseUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport {ERC20PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"./BaseUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\n\n/**\n * @title ERC20BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contracts is an extension of BaseUpgradeable intended to be used\n * as a base for ERC20 tokens contracts.\n *\n * @dev For further details, see \"ERC20BaseUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract ERC20BaseUpgradeable is\n ERC20Upgradeable,\n BaseUpgradeable,\n ERC20PausableUpgradeable\n{\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param name_ The display name of the token.\n * @param symbol_ The symbol of the token.\n */\n function __ERC20Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n string memory name_,\n string memory symbol_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __ERC20_init(name_, symbol_);\n __ERC20Pausable_init_unchained();\n }\n\n function __ERC20Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\n * state from the GlobalPause contract.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, PausableUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\n * The ERC20PausableUpgradeable version is preferred because it also checks that\n * the contract is not paused before allowing the transfer.\n * @inheritdoc ERC20PausableUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n virtual\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\n whenNotPaused\n notBlacklisted(from)\n notBlacklisted(to)\n {\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/GlobalOwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {GlobalOwner} from \"../GlobalOwner.sol\";\n\n/**\n * @title GlobalOwnableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\n * contract (see GlobalOwner.sol). This design facilitates centralized management\n * of ownership for all the Ledgity Yield contracts.\n *\n * @dev Note: The _globalOwner state must be set at initialization-time and for evident\n * security reasons cannot be changed afterwards.\n *\n * @dev For further details, see \"GlobalOwnableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\n /**\n * @notice The GlobalOwner contract the ownership will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalOwner private _globalOwner;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init_unchained(globalOwner_);\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\n // the initial _owner value, calling it would have no effect.\n }\n\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\n _globalOwner = GlobalOwner(globalOwner_);\n }\n\n /**\n * @notice Retrieves the address of GlobalOwner contract.\n * @return The address of the GlobalOwner contract.\n */\n function globalOwner() public view returns (address) {\n return address(_globalOwner);\n }\n\n /**\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\n * from the GlobalOwner contract instead.\n * @return The address of the owner\n */\n function owner() public view override returns (address) {\n return _globalOwner.owner();\n }\n\n /**\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function transferOwnership(address newOwner) public view override onlyOwner {\n newOwner; // Silence unused variable compiler warning\n revert(\"L8\");\n }\n\n /**\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function renounceOwnership() public view override onlyOwner {\n revert(\"L65\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/GlobalPausableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalPause} from \"../GlobalPause.sol\";\n\n/**\n * @title GlobalPausableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit pause state from the specified GlobalPause\n * contract (see GlobalPause.sol). This design facilitates centralized management of\n * pause state for all the Ledgity Yield contracts.\n *\n * @dev Note: The _globalPause state must be set at initialization-time and for evident\n * security reasons cannot be changed afterwards.\n *\n * @dev For further details, see \"GlobalPausableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\n /**\n * @notice The GlobalPause contract the pause state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalPause private _globalPause;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalPause_ The address of the GlobalPause contract.\n */\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n }\n\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\n _globalPause = GlobalPause(globalPause_);\n }\n\n /**\n * @notice Retrieves the address of GlobalPause contract.\n * @return The address of the GlobalPause contract.\n */\n function globalPause() public view returns (address) {\n return address(_globalPause);\n }\n\n /**\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\n * from the GlobalPause contract instead.\n * @return Whether the contract is paused or not.\n */\n function paused() public view virtual override returns (bool) {\n return _globalPause.paused();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/GlobalRestrictableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalBlacklist} from \"../GlobalBlacklist.sol\";\n\n/**\n * @title GlobalRestrictableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit blacklist state from the specified\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\n * centralized management of a blacklist for all the Ledgity Yield contracts.\n *\n * @dev Note: The _globalBlacklist state must be set at initialization-time and for\n * evident security reasons cannot be changed afterwards.\n *\n * @dev For further details, see \"GlobalRestrictableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalRestrictableUpgradeable is Initializable {\n /**\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalBlacklist private _globalBlacklist;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n }\n\n function __GlobalRestrictable_init_unchained(\n address globalBlacklist_\n ) internal onlyInitializing {\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\n }\n\n /**\n * @notice Retrieves the address of GlobalBlacklist contract.\n * @return The address of the GlobalBlacklist contract.\n */\n function globalBlacklist() public view returns (address) {\n return address(_globalBlacklist);\n }\n\n /**\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n */\n modifier notBlacklisted(address account) {\n require(isBlacklisted(account) == false, \"L9\");\n _;\n }\n\n /**\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n * @return Whether the account is blacklisted.\n */\n function isBlacklisted(address account) internal view returns (bool) {\n return _globalBlacklist.isBlacklisted(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/InvestUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"./GlobalPausableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"./GlobalRestrictableUpgradeable.sol\";\nimport \"./base/BaseUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../abstracts/RecoverableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {APRHistory as APRH} from \"../libs/APRHistory.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title InvestUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with utilities to manage an invested token,\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\n *\n * @dev Intuition:\n * This contract primarily exists for code splitting and reusability. It unburdens the\n * LToken contract code, making it easier to understand and maintain.\n *\n * This contract is generic because it may be used in the LDYStaking contract in the future.\n *\n * @dev Definitions:\n * - Investment: The act of depositing or investing tokens into the contract.\n * - Investment period: Time between the start of an investment or the last rewards\n * distribution for an account to the present.\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\n * distributed between investment periods.\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\n *\n * @dev Derived contract must:\n * - Set invested token during initialization\n * - Implement _investmentOf() function\n * - Implement _distributeRewards() function (optional)\n *\n * @dev For further details, see \"InvestmentUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract InvestUpgradeable is BaseUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using APRH for APRH.Pack[];\n\n /**\n * @notice Represents an account's investment period.\n * @param timestamp The timestamp of the most recent rewards distribution.\n * @param ref The reference of the last APR checkpoint at that timestamp.\n */\n struct InvestmentPeriod {\n uint40 timestamp; // Supports dates up to 20/02/36812\n APRH.Reference ref;\n }\n\n /**\n * @notice Represents the investment details of an account.\n * @param period The current investment period of the account.\n * @param virtualBalance May hold a part of account rewards until they are claimed.\n */\n struct AccountDetails {\n InvestmentPeriod period;\n uint256 virtualBalance;\n }\n\n /// @notice Holds a reference to the invested token's contract.\n IERC20Upgradeable private _invested;\n\n /// @notice Holds investment details of each account.\n mapping(address => AccountDetails) internal accountsDetails;\n\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\n APRH.Pack[] private _aprHistory;\n\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\n mapping(address => address) public rewardsRedirectsFromTo;\n mapping(address => address[]) public rewardsRedirectsToFrom;\n\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\n bool private _isClaiming;\n\n /**\n * @notice Emitted to inform listeners about a change in the APR's value.\n * @param newAPRUD7x3 The new APR in UD7x3 format.\n */\n event APRChangeEvent(uint16 newAPRUD7x3);\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param invested_ The address of the invested token contract.\n */\n function __Invest_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address invested_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __Invest_init_unchained(invested_);\n }\n\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\n // Set invested token\n _invested = IERC20Upgradeable(invested_);\n\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\n // of an empty APR history\n _aprHistory.setAPR(0);\n }\n\n /**\n * @notice Retrieves the reference to the invested token contract.\n * @return The reference to the invested token contract.\n */\n function invested() public view returns (IERC20Upgradeable) {\n return _invested;\n }\n\n /**\n * @notice Updates the investment APR. Restricted to owner.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(uint16 aprUD7x3) public onlyOwner {\n _aprHistory.setAPR(aprUD7x3);\n emit APRChangeEvent(aprUD7x3);\n }\n\n /**\n * @notice Retrieves the most recently set APR.\n * @return The current APR in UD7x3 format.\n */\n function getAPR() public view returns (uint16) {\n return _aprHistory.getAPR();\n }\n\n /**\n * @notice Enables redirection of rewards from one account to another.\n * @param from The address of the account to redirect rewards from.\n * @param to The address of the account to redirect rewards to.\n */\n function startRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure the address is not already redirecting rewards\n require(rewardsRedirectsFromTo[from] == address(0), \"L62\");\n\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L12\");\n require(to != address(0), \"L13\");\n\n // Ensure 'from' and 'to' addresses are distinct\n require(from != to, \"L14\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L15\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Activate rewards redirection\n rewardsRedirectsFromTo[from] = to;\n rewardsRedirectsToFrom[to].push(from);\n }\n\n /**\n * @notice Disable an active rewards redirection.\n * @param from The address of the account to stop redirecting rewards from.\n * @param to The address of the account to stop redirecting rewards to.\n */\n function stopRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L16\");\n require(to != address(0), \"L17\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L18\");\n\n // Ensure a rewards redirection was active\n require(rewardsRedirectsFromTo[from] == to, \"L19\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Retrieve 'from' index in the redirection array of 'to'\n int256 fromIndex = -1;\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\n if (rewardsRedirectsToFrom[to][i] == from) {\n fromIndex = int256(i);\n break;\n }\n }\n\n // fromIndex should never be -1 at this point\n assert(fromIndex >= 0);\n\n // Deactivate rewards redirection\n rewardsRedirectsFromTo[from] = address(0);\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\n rewardsRedirectsToFrom[to].length - 1\n ];\n rewardsRedirectsToFrom[to].pop();\n }\n\n /**\n * @notice Retrieves the total amount of tokens invested by the given account.\n * @dev Derived contracts must implement this function.\n * @param account The account to get the investment of.\n * @return The total amount of tokens invested by the given account.\n */\n function _investmentOf(address account) internal view virtual returns (uint256);\n\n /**\n * @notice Distributes a specified amount of rewards to a given account.\n * @dev Derived contracts may optionally implement this function.\n * @dev Implementations must return true to indicate a successful distribution, and\n * false otherwise. If it returns false, the rewards will be added to the account's\n * virtual balance, in order to be claimed later.\n * @param account The account to claim the rewards of.\n * @param amount The amount of rewards to claim.\n * @return Whether the rewards distribution was successfull.\n */\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\n account; // Silence unused variables warning\n amount;\n return false;\n }\n\n /**\n * @notice Computes the rewards accrued over a specified period of time, based on a\n * given APR and amount of invested tokens.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param beginTimestamp The moment the period commenced.\n * @param endTimestamp The moment the period concluded.\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\n * @param investedAmount The amount of tokens deposited/invested during the period.\n * @return The amount of rewards generated during the period.\n */\n function _calculatePeriodRewards(\n uint40 beginTimestamp,\n uint40 endTimestamp,\n uint16 aprUD7x3,\n uint256 investedAmount\n ) internal view returns (uint256) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Compute the number of elapsed years\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\n\n // Compute the growth in invested amount (thanks to rewards)\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\n\n // Compute and return the rewards\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(rewardsSUD, d);\n }\n\n /**\n * @notice Computes the sum of given account's invested amount, plus invested amount\n * of all accounts that recursively redirect rewards to this account.\n * @param account The account to calculate the deep investment of.\n * @return deepInvestedAmount The deep invested amount.\n */\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\n // Consider account's direct investment\n deepInvestedAmount += _investmentOf(account);\n\n // But also the deep investments of all accounts redirecting rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param account The account to calculate the unclaimed rewards of.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\n */\n function _rewardsOf(\n address account,\n bool autocompound\n ) internal view returns (uint256 rewards) {\n // Retrieve account's investment details\n AccountDetails memory details = accountsDetails[account];\n\n // Retrieve account's deep invested amount\n uint256 investedAmount = _deepInvestmentOf(account);\n\n // Return 0 if the account has never invested or has no invested amount\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\n\n // Retrieve reference and data of APR checkpoint at which started investment period\n APRH.Reference memory currRef = details.period.ref;\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\n\n // Retrieve reference of latest APR checkpoint\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\n\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\n // See \"InvestUpgradeable > Rewards calculation > 1)\" section of the whitepaper\n rewards = details.virtualBalance;\n\n // If start checkpoint is not the latest one\n if (!APRH.eq(currRef, latestRef)) {\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // 2) Calculate rewards from investment period start to next checkpoint\n // See \"InvestUpgradeable > Rewards calculation > 2)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n\n // 3) Calculate rewards for each crossed pair of checkpoints\n // See \"InvestUpgradeable > Rewards calculation > 3)\" section of the whitepaper\n while (true) {\n // Set next checkpoint as the current one\n currRef = nextRef;\n currCheckpoint = nextCheckpoint;\n\n // Break if current checkpoint is the latest one\n if (APRH.eq(currRef, latestRef)) break;\n\n // Else, retrieve the new next checkpoint\n nextRef = APRH.incrementReference(currRef);\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // Calculate rewards between the current pair of checkpoints\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n\n // 4) Calculate rewards from the latest checkpoint to now\n // See \"InvestUpgradeable > Rewards calculation > 4)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n } else {\n // 2.bis) Calculate rewards from investment period start to now\n // See \"InvestUpgradeable > Rewards calculation > 2.bis)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n }\n\n /**\n * @notice Recursively resets the investment period of the specified account and of\n * all accounts that directly or indirectly redirect rewards to this account.\n * @param account The account to deeply reset the investment period of.\n */\n function _deepResetInvestmentPeriodOf(address account) internal {\n // Reset account investment period timestamp and APR checkpoint to latest ones\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\n\n // Also reset the ones of all accounts that recursively redirect rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Hook to be invoked before the invested amount of an account changes. It\n * ensures that rewards are distributed and that account's investment period is reset.\n * @param account The account whose invested amount is going to change.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n */\n function _beforeInvestmentChange(address account, bool autocompound) internal {\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\n // minted in LToken._distributeRewards(), this guards against infinite loop.\n if (_isClaiming) return;\n\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\n // As first call will treat both addresses, the second call would be redundant.\n // Therefore, we skip accounts already processed in this block to save up some gas.\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\n\n // If account redirects its rewards\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\n if (redirectRewardsTo != address(0)) {\n // Call hook on redirection target (this will indirectly reset the investment\n // of this source account) and return\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\n return;\n }\n\n // Else, compute account's undistributed/unclaimed rewards\n uint256 rewards = _rewardsOf(account, autocompound);\n\n // If there are some rewards\n if (rewards > 0) {\n // Try to distribute rewards to account\n _isClaiming = true;\n bool distributed = _distributeRewards(account, rewards);\n _isClaiming = false;\n\n // If rewards have not been distributed, accumulate them in account's virtual balance\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\n }\n\n // Finally, deeply reset investment period of the account\n _deepResetInvestmentPeriodOf(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/abstracts/RecoverableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Conracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title RecoverableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with helpers functions that allow recovering\n * assets accidentally sent to them.\n *\n * @dev Note: This abstract contract currently supports only ERC20 tokens. Derived\n * contracts currently do not implement necessary functions to receive Ether or\n * ERC721/ERC1155 tokens.\n *\n * @dev For further details, see \"RecoverableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init(globalOwner_);\n __Recoverable_init_unchained();\n }\n\n function __Recoverable_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Recovers a specified amount of a given token address. Will fail if the\n * contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\n // Ensure the specified amount is not zero\n require(amount > 0, \"L10\");\n\n // Create a reference to token's contract\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\n\n // Ensure there is enough token to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L11\");\n\n // Transfer the recovered token amount to the sender\n tokenContract.safeTransfer(_msgSender(), amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "contracts/src/archive/LToken-before-Aug-22-upgrade.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport {ERC20WrapperUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\";\nimport \"../abstracts/base/ERC20BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"../abstracts/InvestUpgradeable.sol\";\nimport {LDYStaking} from \"../DummyLDYStaking.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport {ITransfersListener} from \"../interfaces/ITransfersListener.sol\";\n\n/**\n * @title LToken\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e,\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\n * the form of additional L-Tokens, which are auto-compounded over time.\n *\n * @dev Definitions:\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\n * - Instant: Processed immediately.\n * - Requested: Queued for later processing.\n * - Big Requested: A requested withdrawal exceeding half of the retention rate.\n * - (Withdrawal) queue: An list of all requested withdrawals sorted by priority.\n * - Request ID: The index of a withdrawal request in the queue array.\n * - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain.\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\n * expected ways and are so considered as safe to use by the contract.\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\n * processing.\n *\n * Note that words between parenthesis are sometimes omitted for brevity.\n *\n * @dev Security: This contract can safely receive funds immediately after initialization.\n * (i.e., there is no way for funds to be sent to non-owned addresses). It is however\n * recommended to replace ASAP owner and fund wallets by multi-sig wallets.\n *\n * @dev For further details, see \"LToken\" section of whitepaper.\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n * @custom:security-contact security@ledgity.com\n */\ncontract OldLToken1 is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @dev Represents type of actions triggering ActivityEvent events.\n enum Action {\n Deposit,\n Withdraw\n }\n\n /// @dev Represents different status of actions triggering ActivityEvent events.\n enum Status {\n Queued,\n Cancelled,\n Success\n }\n\n /**\n * @notice Represents a withdrawal request in the queue.\n * @dev A request fits in a single storage slot (32 bytes).\n * @param account The account that initiated the request.\n * @param amount The amount of underlying tokens requested.\n */\n struct WithdrawalRequest {\n address account; // 20 bytes\n uint96 amount; // 12 bytes\n }\n\n /// @notice Upper limit of retention rate.\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\n\n /// @notice Used in activity events to represent the absence of request ID.\n int256 private constant NO_ID = -1;\n\n /// @notice Holds a reference to the LDYStaking contract.\n LDYStaking public ldyStaking;\n\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\n address payable public withdrawer;\n\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\n address public fund;\n\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\n uint32 public feesRateUD7x3;\n\n /// @notice Holds the retention rate in UD7x3 format.\n uint32 public retentionRateUD7x3;\n\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\n uint256 public unclaimedFees;\n\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\n uint256 public totalQueued;\n\n /**\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\n */\n uint256 public usableUnderlyings;\n\n /// @notice Holds an ordered list of active withdrawal requests.\n WithdrawalRequest[] public withdrawalQueue;\n\n /// @notice Holds the index of the next withdrawal request to process in the queue.\n uint256 public withdrawalQueueCursor;\n\n /**\n * @notice Holds a list of all currently frozen withdrawal requests.\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\n * it from blocking the queue.\n */\n WithdrawalRequest[] public frozenRequests;\n\n /**\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\n */\n ITransfersListener[] public transfersListeners;\n\n /**\n * @notice Emitted to inform listeners about a change in the contract's TVL.\n * @dev TVL = realTotalSupply()\n * @param newTVL The new TVL of the contract.\n */\n event TVLChangeEvent(uint256 newTVL);\n\n /**\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\n * @param account The account involved in the activity.\n * @param action The type of activity.\n * @param amount The amount of underlying tokens involved in the activity.\n * @param newStatus The new status of the activity.\n */\n event ActivityEvent(\n int256 indexed id,\n address indexed account,\n Action indexed action,\n uint256 amount,\n uint256 amountAfterFees,\n Status newStatus\n );\n\n /**\n * @notice Emitted to inform listeners that some rewards have been minted.\n * @param account The account that received the rewards.\n * @param balanceBefore The balance of the account before the minting.\n * @param rewards The amount of minted rewards.\n */\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\n\n /// @notice Reverts if the function caller is not the withdrawer wallet.\n modifier onlyWithdrawer() {\n require(_msgSender() == withdrawer, \"L39\");\n _;\n }\n\n /// @notice Reverts if the function caller is not the fund wallet.\n modifier onlyFund() {\n require(_msgSender() == fund, \"L40\");\n _;\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyStaking_,\n address underlyingToken\n ) public initializer {\n // Initialize ERC20 base.\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\n __ERC20Base_init(\n globalOwner_,\n globalPause_,\n globalBlacklist_,\n string(abi.encodePacked(\"Ledgity \", underlyingSymbol)),\n string(abi.encodePacked(\"L\", underlyingSymbol))\n );\n\n // IMPORTANT: Below calls must not be restricted to owner at any point.\n // This is because the GlobalOwner contract may not be a fresh one, and so\n // the contract deployer may not be the owner anymore after ERC20Base init.\n\n // Initialize other parents contracts.\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\n __Invest_init_unchained(address(this));\n\n // Set LDYStaking contract\n ldyStaking = LDYStaking(ldyStaking_);\n\n // Set initial withdrawal fees rate to 0.3%\n feesRateUD7x3 = 300;\n\n // Set initial retention rate to 10%\n retentionRateUD7x3 = 10_000;\n\n // Default withdrawer and fund wallet to contract owner address. This prevents\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\n withdrawer = payable(owner());\n fund = payable(owner());\n }\n\n /**\n * @notice Required override of decimals() which is implemented by both\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\n * decimals amount of the underlying stablecoin token.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function decimals()\n public\n view\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\n returns (uint8)\n {\n return ERC20WrapperUpgradeable.decimals();\n }\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @notice Updates the current withdrawal fee rate.\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\n */\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\n feesRateUD7x3 = feesRateUD7x3_;\n }\n\n /**\n * @notice Updates the current underlying token retention rate.\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\n * deposited assets will ever be exposed in this contract (reduces attack surface).\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\n */\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \"L41\");\n retentionRateUD7x3 = retentionRateUD7x3_;\n }\n\n /**\n * @notice Updates the address of LDYStaking contract.\n * @param ldyStakingAddress The address of the new LDYStaking contract.\n */\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\n ldyStaking = LDYStaking(ldyStakingAddress);\n }\n\n /**\n * @notice Updates the address of the withdrawer wallet.\n * @param withdrawer_ The address of the new withdrawer wallet.\n */\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\n // Ensure address is not the zero address (pre-processing fees would be lost else)\n require(withdrawer_ != address(0), \"L63\");\n\n // Set new withdrawer wallet's address\n withdrawer = withdrawer_;\n }\n\n /**\n * @notice Updates the address of the fund wallet.\n * @param fund_ The address of the new fund wallet.\n */\n function setFund(address payable fund_) public onlyOwner {\n // Ensure address is not the zero address (deposited tokens would be lost else)\n require(fund_ != address(0), \"L64\");\n\n // Set new fund wallet's address\n fund = fund_;\n }\n\n /**\n * @notice Adds a new contract to the L-Token transfers list.\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\n * specified contract will be called.\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\n * contracts that are not owned by the Ledgity team.\n * @param listenerContract The address of the new transfers listener contract.\n */\n function listenToTransfers(address listenerContract) public onlyOwner {\n transfersListeners.push(ITransfersListener(listenerContract));\n }\n\n /**\n * @notice Removes a contract from the L-Token transfers list.\n * @dev The onLTokenTransfer() function of the specified contract will not be called\n * anymore each time a L-Token transfer occurs.\n * @param listenerContract The address of the listener contract.\n */\n function unlistenToTransfers(address listenerContract) public onlyOwner {\n // Find index of listener contract in transferListeners array\n int256 index = -1;\n uint256 transfersListenersLength = transfersListeners.length;\n for (uint256 i = 0; i < transfersListenersLength; i++) {\n if (address(transfersListeners[i]) == listenerContract) {\n index = int256(i);\n break;\n }\n }\n\n // Revert if given contract wasn't listening to transfers\n require(index > -1, \"L42\");\n\n // Else, remove transfers listener contract from listeners array\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\n transfersListeners.pop();\n }\n\n /**\n * @notice Retrieves the amount of given account's not yet minted rewards.\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\n * context of LToken, this function returns the amount of rewards that have not been\n * distributed/minted yet to the specified account.\n * @dev This is particularly useful for off-chain services to display charts and\n * statistics, as seen in the Ledgity Yield's frontend.\n * @param account The account to check the unminted rewards of.\n * @return The amount of account's unminted rewards.\n */\n function unmintedRewardsOf(address account) public view returns (uint256) {\n return _rewardsOf(account, true);\n }\n\n /**\n * @notice Retrieves the \"real\" balance of an account, i.e., excluding its not yet\n * minted/distributed rewards.\n * @param account The account to check the real balance of.\n * @return The real balance of the account.\n */\n function realBalanceOf(address account) public view returns (uint256) {\n return super.balanceOf(account);\n }\n\n /**\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\n * not been yet minted to the specified account.\n * @param account The account to check the total balance of.\n * @return The total balance of the account.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return realBalanceOf(account) + unmintedRewardsOf(account);\n }\n\n /**\n * @notice Returns the \"real\" amount of existing L-Tokens, i.e., excluding not yet\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\n * @return The real total supply of L-Tokens.\n */\n function realTotalSupply() public view returns (uint256) {\n return super.totalSupply();\n }\n\n /**\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\n * fees and L-Tokens currently in the withdrawal queue.\n * @return The total supply of L-Tokens.\n */\n function totalSupply() public view override returns (uint256) {\n return realTotalSupply() + totalQueued + unclaimedFees;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address.\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\n * token from being the underlying token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the underlying token\n require(tokenAddress != address(underlying()), \"L43\");\n\n // Proceed to recovery\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @notice Recovers underlying tokens accidentally sent to the contract.\n * @dev To prevent owner from being able to drain the contract, this function only\n * allows recovering \"unusable\" underlying tokens, i.e., tokens that have not been\n * sent through fund() or deposit() functions.\n */\n function recoverUnderlying() external onlyOwner {\n // Compute the recoverable amount by taking the difference between the contract's\n // balance and the amount of usable underlying tokens\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\n\n // Revert if there is nothing to recover\n require(recoverableAmount > 0, \"L44\");\n\n // Else, proceed to underlying tokens recovery\n super.recoverERC20(address(underlying()), recoverableAmount);\n }\n\n /**\n * @notice Retrieves the amount of underlying tokens invested by the given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\n * LToken contract, the investment of an account is equal to its real balance.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return realBalanceOf(account);\n }\n\n /**\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract so\n * it can distribute rewards to accounts before each period reset.\n * @dev InvestUpgradeable contract already ensure that amount > 0.\n * @inheritdoc InvestUpgradeable\n */\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\n // Inform listeners of the rewards minting\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\n\n // Mint L-Tokens rewards to account\n _mint(account, amount);\n\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\n return true;\n }\n\n /**\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\n * called each time an account's balance is going to change.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\n * @inheritdoc ERC20BaseUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\n\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\n if (from != address(0)) _beforeInvestmentChange(from, true);\n if (to != address(0)) _beforeInvestmentChange(to, true);\n }\n\n /**\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\n * transfers listeners.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already checked in _beforeTokenTransfer().\n * @inheritdoc ERC20Upgradeable\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\n super._afterTokenTransfer(from, to, amount);\n\n // If some L-Token have been burned/minted, inform listeners of a TVL change\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\n\n // Trigger onLTokenTransfer() functions of all the transfers listeners\n for (uint256 i = 0; i < transfersListeners.length; i++) {\n transfersListeners[i].onLTokenTransfer(from, to, amount);\n }\n }\n\n /**\n * @notice Computes the maximum amount of underlying tokens that should be retained\n * by the contract (based on retention rate).\n * @return amount The expected amount of retained underlying tokens.\n */\n function getExpectedRetained() public view returns (uint256 amount) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert totalSupply and retentionRate to SUD\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\n\n // Compute and return expected retained amount\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(expectedRetainedSUD, d);\n }\n\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\n function _transferExceedingToFund() internal {\n // Retrieve the expected amount retained\n uint256 expectedRetained = getExpectedRetained();\n\n // If usable underlyings are less than or equal to expected retained, return\n if (usableUnderlyings <= expectedRetained) return;\n\n // Else, exceeding amount is equal to difference between those values\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= exceedingAmount;\n\n // Transfer the exceeding amount to the fund wallet\n underlying().safeTransfer(fund, exceedingAmount);\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L45\");\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\n * Use deposit() function instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L46\");\n }\n\n /**\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\n * @param amount The amount of underlying tokens to deposit.\n */\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough underlying tokens to deposit\n require(underlying().balanceOf(_msgSender()) >= amount, \"L47\");\n\n // Update usable underlyings balance accordingly\n usableUnderlyings += amount;\n\n // Inform listeners of the deposit activity event\n emit ActivityEvent(NO_ID, _msgSender(), Action.Deposit, amount, amount, Status.Success);\n\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\n super.depositFor(_msgSender(), amount);\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\n * given amount.\n * @param account The account initiating the withdrawal.\n * @param amount The amount of the withdrawal.\n */\n function getWithdrawnAmountAndFees(\n address account,\n uint256 amount\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\n // If the account is eligible to staking tier 2, no fees are applied\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\n\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert amount and fees rate to SUD\n uint256 amountSUD = SUD.fromAmount(amount, d);\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\n\n // Compute fees and withdrawn amount (initial amount minus fees)\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\n fees = SUD.toAmount(feesSUD, d);\n withdrawnAmount = amount - fees;\n }\n\n /**\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\n * enough underlying tokens to cover the withdrawal.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestWithdrawal() function otherwise.\n * @param amount The amount L-Tokens to withdraw.\n */\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L48\");\n\n // Can the contract cover this withdrawal plus all already queued requests?\n bool cond1 = totalQueued + amount <= usableUnderlyings;\n\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\n\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\n if (!(cond1 || cond2)) revert(\"L49\");\n\n // Else, retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\n\n // Increase unclaimed fees amount accordingly\n unclaimedFees += fees;\n\n // Decrease usable underlyings balance accordingly\n usableUnderlyings -= withdrawnAmount;\n\n // Inform listeners of this instant withdrawal activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Withdraw,\n amount,\n withdrawnAmount,\n Status.Success\n );\n\n // Burn withdrawal fees from the account\n _burn(_msgSender(), fees);\n\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\n super.withdrawTo(_msgSender(), withdrawnAmount);\n }\n\n /**\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\n * amount of underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.004 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n * @param amount The amount L-Tokens to withdraw.\n */\n function requestWithdrawal(\n uint256 amount\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L53\");\n\n // Ensure the requested amount doesn't overflow uint96\n require(amount <= type(uint96).max, \"L54\");\n\n // Ensure the sender attached the pre-paid processing gas fees\n require(msg.value == 0.004 * 10 ** 18, \"L55\");\n\n // Create withdrawal request data\n WithdrawalRequest memory request = WithdrawalRequest({\n account: _msgSender(),\n amount: uint96(amount)\n });\n\n // Will hold the request ID\n uint256 requestId;\n\n // Append request to the withdrawal queue:\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\n withdrawalQueueCursor--;\n requestId = withdrawalQueueCursor;\n withdrawalQueue[requestId] = request;\n }\n // - At the end else\n else {\n withdrawalQueue.push(request);\n requestId = withdrawalQueue.length - 1;\n }\n\n // Increase total amount queued accordingly\n totalQueued += amount;\n\n // Inform listeners of this new queued withdrawal activity event\n emit ActivityEvent(\n int256(requestId),\n _msgSender(),\n Action.Withdraw,\n amount,\n amount,\n Status.Queued\n );\n\n // Burn withdrawal L-Tokens amount from account's balance\n _burn(_msgSender(), amount);\n\n // Forward pre-paid processing gas fees to the withdrawer wallet\n (bool sent, ) = withdrawer.call{value: msg.value}(\"\");\n require(sent, \"L56\");\n }\n\n /**\n * @notice Processes queued withdrawal requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n * @dev For further details, see \"LToken > Withdrawals\" section of whitepaper.\n */\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\n // Accumulators variables, will be written on-chain after the loop\n uint256 cumulatedFees = 0;\n uint256 cumulatedWithdrawnAmount = 0;\n uint256 nextRequestId = withdrawalQueueCursor;\n\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\n // requests are increasing the queue length when moved at the end of the queue.\n uint256 queueLength = withdrawalQueue.length;\n\n // Iterate over requests to be processed\n while (nextRequestId < queueLength) {\n // Stop processing requests if there is not enough gas left to continue the\n // loop and properly end the function call. This prevents an attacker from\n // blocking the withdrawal processing by creating a ton of tiny requests so\n // this function call cannot fit anymore in block gas limit.\n if (gasleft() < 45000) break;\n\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\n\n // Skip empty request (processed big requests or cancelled requests)\n if (request.account == address(0)) {}\n //\n // If account has been blacklisted since request emission\n else if (isBlacklisted(request.account)) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request in the frozen requests list\n frozenRequests.push(request);\n }\n //\n // Or if request is a big request, move it at the end of the queue for now.\n // This request will be processed manually later using processBigQueuedRequest()\n else if (request.amount > getExpectedRetained() / 2) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request at the end of the queue\n withdrawalQueue.push(request);\n }\n //\n // Else, continue request processing\n else {\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Break if the contract doesn't hold enough funds to cover the request\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\n\n // Accumulate fees and withdrawn amount\n cumulatedFees += fees;\n cumulatedWithdrawnAmount += withdrawnAmount;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(nextRequestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Transfer underlying tokens to account. Burning L-Tokens is not required\n // as equestWithdrawal() already did it.\n // Security note: Re-entrancy warning are disabled as the request has\n // just been deleted from the queue, it will so be skipped if trying to\n // process it again.\n // slither-disable-next-line reentrancy-no-eth\n underlying().safeTransfer(request.account, withdrawnAmount);\n }\n\n // Increment next request ID\n nextRequestId++;\n }\n\n // Increase unclaimed fees by the amount of cumulated fees\n unclaimedFees += cumulatedFees;\n\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\n usableUnderlyings -= cumulatedWithdrawnAmount;\n\n // Decrease total amount queued by the cumulated amount requested\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\n\n // Update new queue cursor\n withdrawalQueueCursor = nextRequestId;\n\n // Retention rate cannot exceeds as the withdrawal decreases both usable\n // underlyings and expected retained amounts by the same number and as the\n // expected retained amount is a subset of usable underlyings amount.\n }\n\n /**\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\n * the retention rate).\n * @dev In contrast to non-big requests processing, this function will uses to fund\n * wallet's balance to fill the request. This allows processing requests that are\n * greater than retention rate without having to exceed this rate on the contract.\n * @param requestId The ID of the big request to process.\n */\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure the request is active\n require(request.account != address(0), \"L66\");\n\n // Ensure the request emitter has not been blacklisted since request emission\n require(!isBlacklisted(request.account), \"L50\");\n\n // Ensure this is indeed a big request\n require(request.amount > getExpectedRetained() / 2, \"L51\");\n\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\n uint256 fundBalance = underlying().balanceOf(fund);\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \"L52\");\n\n // Increase amount of unclaimed fees accordingly\n unclaimedFees += fees;\n\n // Decrease total queued amount by request amount\n totalQueued -= request.amount;\n\n // Increment queue cursor if request was the next request to be processed\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success\n );\n\n // Remove request from queue\n delete withdrawalQueue[requestId];\n\n // If fund wallet's balance can cover request, rely on it only\n if (withdrawnAmount <= fundBalance) {\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\n }\n // Else, cover request from both fund wallet and contract balances\n else {\n // Compute amount missing from fund wallet to cover request\n uint256 missingAmount = withdrawnAmount - fundBalance;\n\n // Decrease usable amount of underlying tokens accordingly\n usableUnderlyings -= missingAmount;\n\n // Transfer entire fund balance to request's emitter\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\n\n // Transfer missing amount from contract balance to request emitter\n underlying().safeTransfer(request.account, missingAmount);\n }\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Cancels a given withdrawal request. The request emitter receive back its\n * L-Tokens and no fees will be charged.\n * @param requestId The ID of the withdrawal request to cancel.\n */\n function cancelWithdrawalRequest(\n uint256 requestId\n ) public whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure request belongs to caller\n require(_msgSender() == request.account, \"L57\");\n\n // Decrease total amount queued accordingly\n totalQueued -= request.amount;\n\n // Delete the withdrawal request from queue\n delete withdrawalQueue[requestId];\n\n // Inform listeners of this cancelled withdrawal request activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Cancelled\n );\n\n // Mint back L-Tokens to account\n _mint(request.account, uint256(request.amount));\n }\n\n /**\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\n * whenever those are required to fulfill some withdrawal requests.\n * @dev The function will revert if repatriated amount makes the contract exceeding\n * the retention rate.\n * @param amount The amount of underlying tokens to repatriate.\n */\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\n // Ensure the fund wallet has enough funds to repatriate\n require(amount <= underlying().balanceOf(fund), \"L58\");\n\n // Calculate new contract usable balance\n uint256 newBalance = usableUnderlyings + amount;\n\n // Ensure the new balance doesn't exceed the retention rate\n require(newBalance <= getExpectedRetained(), \"L59\");\n\n // Increase usable underlyings amount by repatriated amount\n usableUnderlyings += amount;\n\n // Transfer amount from fund wallet to contract\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /// @notice Used by owner to claim fees generated from successful withdrawals.\n function claimFees() external onlyOwner {\n // Ensure there are some fees to claim\n require(unclaimedFees > 0, \"L60\");\n\n // Ensure the contract holds enough underlying tokens to cover fees\n require(usableUnderlyings >= unclaimedFees, \"L61\");\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= unclaimedFees;\n\n // Store fees amount in memory and reset unclaimed fees amount\n uint256 fees = unclaimedFees;\n unclaimedFees = 0;\n\n // Transfer unclaimed fees to owner\n underlying().safeTransfer(owner(), fees);\n }\n}\n" - }, - "contracts/src/GenericERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n/**\n * @notice Used for testing purposes only.\n * It represents:\n * - a FIAT-based stablecoin when used to test the LToken contract,\n * - the $LDY token when used to test the LDYStaking contract.\n * This contract accept decimals as constructor argument, so it can be used to to\n * easily test different decimals scenarios.\n */\ncontract GenericERC20 is ERC20, ERC20Burnable {\n uint8 private _decimals;\n\n constructor(string memory name, string memory symbol, uint8 decimals_) ERC20(name, symbol) {\n _decimals = decimals_;\n }\n\n function mint(uint256 amount) public {\n _mint(msg.sender, amount);\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n\n /**\n * Used in tests to test different decimals scenarios.\n */\n function setDecimals(uint8 decimals_) public {\n _decimals = decimals_;\n }\n}\n" - }, - "contracts/src/dev/LDYStaking.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport \"../abstracts/base/BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"../abstracts/InvestUpgradeable.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n// Libraries & interfaces\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title LDYStaking\n * @author Lila Rest (lila@ledgity.com)\n * @notice This contract powers the $LDY staking mechanism of the Ledgity Yield app. It allows\n * users to stake their $LDY tokens and earn rewards in $LDY.\n * @dev\n * Security note: InvestmentUpgradeable.AccountInfos.virtualBalance (uint88) allows storing up\n * to 309,485,009 $LDY which is far enough because it represents more than 3 times $LDY max\n * supply.\n *\n * Design note: This contract considers that tiers start at 1, 0 is considered as not elligible\n * to any tier.\n *\n * @dev WARNING: This contract assumes that the $LDY has 18 decimals and is not designed\n * to work with other decimals numbers.\n *\n * @dev For further details, see \"LDYStaking\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n */\ncontract WIP_LDYStaking is BaseUpgradeable, InvestUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @dev Represents the stake infos of an account.\n * @param amount The amount of staked $LDY\n * @param lockEnd The timestamp at which the stake is unlocked\n */\n struct AccountStake {\n uint216 amount; // Allows storing more $LDY than its max supply\n uint40 lockEnd; // Allows datetime up to 20/02/36812\n }\n\n /// @dev Hundred in UD60x18 format\n uint256 private constant HUNDRED_UD60x18 = 100 * 1e18;\n\n /// @dev Holds the time (in seconds) during which staked $LDY are locked\n uint40 public stakeLockDuration;\n\n /// @dev Holds the fees rate (in SUD format) taxed when account requests prematurate unlock\n uint32 public unlockFeesRateUD7x3;\n\n /// @dev Holds a mapping of account's stake infos\n mapping(address => AccountStake) private accountsStakes;\n\n /// @dev Holds amount of $LDY to be elligible to staking tier\n uint256[] _tiers;\n\n /// @dev Holds the total amount staked\n uint256 public totalStaked;\n\n /// @dev Holds the total amount of $LDY to be distributed as rewards\n uint256 public rewardsReserve;\n\n /**\n * @dev Emitted to inform listeners of a change in the total amount staked\n * @param newTotalStaked The new total amount staked\n */\n event TotalStakedUpdateEvent(uint256 newTotalStaked);\n\n /**\n * @dev Replaces the constructor() function in context of an upgradeable contract.\n * See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract\n * @param globalPause_ The address of the GlobalPauser contract\n * @param globalBlacklist_ The address of the GlobalBlacklist contract\n * @param ldyTokenAddress The address of the $LDY token\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyTokenAddress\n ) public initializer {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __Invest_init_unchained(ldyTokenAddress);\n\n // Initialize stakeLockDuration to 90 days\n stakeLockDuration = 90 days;\n }\n\n /**\n * @dev Override of RecoverableUpgradeable.recoverERC20() that prevents recovered\n * token from being the invested $LDY token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the $LDY token\n require(tokenAddress != address(invested()), \"L21\");\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @dev Allows recovering $LDY tokenS accidentally sent to this contract. To prevent\n * owner from draining funds from the contract, this function only allows recovering\n * \"recoverable\" underlying tokens, i.e., tokens that have neither been deposited\n * through `stake()` function nor through the `fund()` one.\n */\n function recoverLDY() public onlyOwner {\n // Compute the amount of $LDY that can be recovered by taking the difference between\n // the contract's $LDY balance and the total amount staked plus the rewards reserve\n uint256 recoverableAmount = invested().balanceOf(address(this)) -\n (totalStaked + rewardsReserve);\n\n // Revert if there are no recoverable $LDY\n require(recoverableAmount > 0, \"L22\");\n\n // Else transfer the recoverable $LDY to the owner\n super.recoverERC20(address(invested()), recoverableAmount);\n }\n\n /**\n * @dev Implementation of InvestUpgradeable._investmentOf(). Required by parent contract\n * to calculate rewards of an account. In this contract the investment of an account is\n * equal to the amount of $LDY staked by the given account.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return stakeOf(account);\n }\n\n /**\n * @dev External implementation of InvestmentUpgradeable._rewardsOf() allowing\n * off-chain apps to easily compute the unclaimed rewards of a given account.\n * @param account The account to check the rewards of\n * @return The amount of unclaimed rewards of the account\n */\n function rewardsOf(address account) external view returns (uint256) {\n return _rewardsOf(account, false);\n }\n\n /**\n * @dev Getter that reads and return the amount staked by a given account.\n * @param account The account to check the stake of\n */\n function stakeOf(address account) public view returns (uint256) {\n return accountsStakes[account].amount;\n }\n\n /**\n * @dev Getter that reads and return the lock end of a given account.\n * @param account The account to check the lock end of\n */\n function lockEndOf(address account) public view returns (uint40) {\n return accountsStakes[account].lockEnd;\n }\n\n /**\n * @notice Computes the increases of tier lock time for a given account extending\n * its staking by a given \"added amount\".\n * @dev SUD is not used as precision loss on lock duration increase are acceptable.\n * Not using it allows to save gas and make code less complex.\n * @param account The account to check the lock end increase of\n * @param addedAmount The amount of $LDY added by the account to its stake\n */\n function _getLockDurationIncrease(\n address account,\n uint256 addedAmount\n ) internal view returns (uint40 lockDurationIncrease) {\n // Retrieve account's stake infos\n AccountStake memory accountStake = accountsStakes[account];\n\n // If the account has no previous stake, return a full lock duration\n if (accountStake.amount == 0) return stakeLockDuration;\n\n // Convert added amount, account stake and stake lock duration to SUD\n uint256 addedAmountSUD = SUD.fromAmount(addedAmount, 18);\n uint256 accountStakeSUD = SUD.fromAmount(accountStake.amount, 18);\n uint256 stakeLockDurationSUD = SUD.fromInt(stakeLockDuration, 18);\n\n // Calculate the stake growth\n uint256 growthRateSUD = (addedAmountSUD * SUD.fromInt(100, 18)) / accountStakeSUD;\n\n // Compute the lock end increase proportionnally to stake growth\n uint256 lockDurationIncreaseSUD = (stakeLockDurationSUD * growthRateSUD) /\n SUD.fromInt(100, 18);\n uint256 _lockDurationIncrease = SUD.toInt(lockDurationIncreaseSUD, 18);\n\n // Cast _lockDurationIncrease to uint40.\n // If the lock end is going to overflow uint40, set it to the uint40 max value\n lockDurationIncrease = _lockDurationIncrease > type(uint40).max\n ? type(uint40).max\n : uint40(_lockDurationIncrease);\n\n // Compute the remaining lock duration of the account\n // If the lock end is in the past, the remaining lock duration is 0\n uint40 remainingLockDuration = accountStake.lockEnd < uint40(block.timestamp)\n ? 0\n : accountStake.lockEnd - uint40(block.timestamp);\n\n // Compute the sum of remaining and new lock durations\n // uint256 is used to avoid overflow\n uint256 lockDurationsSum = uint256(remainingLockDuration) + uint256(lockDurationIncrease);\n\n // Ensure the new lock duration will not exceed the stakeLockDuration\n lockDurationIncrease = lockDurationsSum > stakeLockDuration\n ? stakeLockDuration - remainingLockDuration\n : lockDurationIncrease;\n }\n\n /**\n * @dev Computes the new lock end timestamp of a given account and amount added to\n * its stake.\n * @param account The account to check the new lock end of\n * @param addedAmount The amount of $LDY added by the account to its stake\n */\n function getNewLockEndFor(address account, uint216 addedAmount) public view returns (uint40) {\n return uint40(block.timestamp) + _getLockDurationIncrease(account, addedAmount);\n }\n\n /**\n * @dev Setter for the prematurate unlock fees/tax rate. Restricted to owner.\n * @param unlockFeesRateUD7x3_ The new unlock fees rate in UD7x3 format\n */\n function setUnlockFeesRate(uint32 unlockFeesRateUD7x3_) public onlyOwner {\n unlockFeesRateUD7x3 = unlockFeesRateUD7x3_;\n }\n\n /**\n * @dev Setter for the stake lock duration. Restricted to owner.\n * @param stakeLockDuration_ The new stake lock duration\n */\n function setStakeLockDuration(uint40 stakeLockDuration_) public onlyOwner {\n stakeLockDuration = stakeLockDuration_;\n }\n\n /**\n * @dev Allows the owner to fill the $LDY rewards reserve (used to reward stakers).\n * @param amount The amount of $LDY to deposit\n */\n function fuel(uint256 amount) external onlyOwner {\n // Ensure the amount is not 0\n require(amount > 0, \"L23\");\n\n // Increase rewards reserve amount\n rewardsReserve += amount;\n\n // Transfer $LDY tokens from the caller to this contract\n invested().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /**\n * @dev Prematurely unlocks the stake of the caller against a fee rate defined\n * by unlockFeesRateUD7x3. The entire fee is burned as a way to support the token's\n * ecosystem.\n */\n function unlock() external whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve account stake infos\n AccountStake memory accountStake = accountsStakes[_msgSender()];\n\n // Ensure the account has a locked stake\n require(accountStake.lockEnd > block.timestamp, \"L24\");\n\n // Unlock stake by setting lock time to now\n accountStake.lockEnd = uint40(block.timestamp);\n\n // Calculate unlock fees/tax\n uint256 unlockFeesRateSUD = SUD.fromRate(unlockFeesRateUD7x3, 18);\n uint256 accountStakeSUD = SUD.fromAmount(accountStake.amount, 18);\n uint256 feesSUD = (accountStakeSUD * unlockFeesRateSUD) / SUD.fromInt(100, 18);\n uint256 fees = SUD.toAmount(feesSUD, 18);\n\n // Remove fees from the account stake\n accountStake.amount -= uint216(fees);\n\n // Write the new account stake infos\n accountsStakes[_msgSender()] = accountStake;\n\n // Burn unlock fees\n ERC20Burnable(address(invested())).burn(fees);\n }\n\n /**\n * @dev Allows a user to stake a given amount of $LDY tokens.\n * @param amount The amount of $LDY tokens to stake\n */\n function stake(uint216 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the amount is not 0\n require(amount > 0, \"L25\");\n\n // Ensure the account has enough $LDY tokens to stake\n require(invested().balanceOf(_msgSender()) >= amount, \"L26\");\n\n // Reset account's investment period\n _beforeInvestmentChange(_msgSender(), false);\n\n // Retrieve account stake infos\n AccountStake memory accountStake = accountsStakes[_msgSender()];\n\n // Update the amount staked by the account and the total amount staked\n accountStake.amount += amount;\n totalStaked += amount;\n\n // Inform listeners about the change in total staked amount\n emit TotalStakedUpdateEvent(totalStaked);\n\n // Update the end of the lock period\n accountStake.lockEnd = getNewLockEndFor(_msgSender(), amount);\n\n // Write the new account stake infos\n accountsStakes[_msgSender()] = accountStake;\n\n // Transfer staked $LDY tokens to the contract\n invested().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /**\n * @dev Allows a user to unstaking (withdraw) a given amount of $LDY tokens.\n * @param amount The amount of $LDY tokens to unstake\n */\n function unstake(uint216 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the amount is not 0\n require(amount > 0, \"L27\");\n\n // Ensure the account has enough $LDY tokens to unstake\n require(stakeOf(_msgSender()) >= amount, \"L28\");\n\n // Retrieve account stake infos\n AccountStake memory accountStake = accountsStakes[_msgSender()];\n\n // Ensure the account is not in lock period\n require(accountStake.lockEnd <= block.timestamp, \"L29\");\n\n // Reset its investment period\n _beforeInvestmentChange(_msgSender(), false);\n\n // Update the amount staked by the account and the total amount staked\n accountStake.amount -= amount;\n totalStaked -= amount;\n\n // Inform listeners about the change in total staked amount\n emit TotalStakedUpdateEvent(totalStaked);\n\n // Write the new account stake infos\n accountsStakes[_msgSender()] = accountStake;\n\n // Transfer withdrawn $LDY tokens to the account\n invested().safeTransfer(_msgSender(), amount);\n }\n\n /**\n * @dev Allows the caller to claim its currently unclaimed rewards.\n */\n function claim() public whenNotPaused notBlacklisted(_msgSender()) {\n // Reset account investment period. This will accumualte current unclaimed\n // rewards into the account's virtual balance.\n _beforeInvestmentChange(_msgSender(), false);\n\n // Retrieve and reset account's unclaimed rewards from virtual balance\n uint256 rewards = accountsDetails[_msgSender()].virtualBalance;\n\n // Ensure there are some rewards to claim\n require(rewards > 0, \"L30\");\n\n // Reset account's virtual balance\n accountsDetails[_msgSender()].virtualBalance = 0;\n\n // Ensure the contract has enough rewards to distribute\n require(rewardsReserve >= rewards, \"L31\");\n\n // Decreases the total amount of remaining rewards to distribute\n rewardsReserve -= rewards;\n\n // Transfer rewards to the account\n invested().safeTransfer(_msgSender(), rewards);\n }\n\n /**\n * @dev Allows the caller to compound its currently unclaimed rewards to its stake.\n * Note that we don't update the lock end here, as it applies only to $LDY deposited\n * through the stake() function, not to rewards.\n */\n function compound() external whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve account stake infos\n AccountStake memory accountStake = accountsStakes[_msgSender()];\n\n // Reset account investment period. This will accumualte current unclaimed\n // rewards into the account's virtual balance.\n _beforeInvestmentChange(_msgSender(), false);\n\n // Retrieve and reset account's unclaimed rewards from virtual balance\n uint256 rewards = accountsDetails[_msgSender()].virtualBalance;\n\n // Ensure there are some rewards to claim\n require(rewards > 0, \"L32\");\n\n // Reset account's virtual balance\n accountsDetails[_msgSender()].virtualBalance = 0;\n\n // Ensure the contract has enough rewards to distribute\n require(rewardsReserve >= rewards, \"L33\");\n\n // Decreases the total amount of remaining rewards to distribute\n rewardsReserve -= rewards;\n\n // Update the amount staked by the account and the total amount staked\n accountStake.amount += uint216(rewards);\n totalStaked += rewards;\n\n // Inform listeners about the change in total staked amount\n emit TotalStakedUpdateEvent(totalStaked);\n\n // Write the new account stake infos\n accountsStakes[_msgSender()] = accountStake;\n }\n\n /**\n * @dev Sets the amount of $LDY tokens that must be staked to be elligible to a given\n * staking tier.\n * @param tier The tier number (not its index in the array)\n * @param amount The amount of $LDY tokens to stake to be elligible to the tier\n */\n function setTier(uint256 tier, uint256 amount) public onlyOwner {\n // Ensure the tier is > 0 (as it shouldn't be an index)\n require(tier > 0, \"L34\");\n\n // Retrieve tier index from tier number\n uint256 tierIndex = tier - 1;\n\n // Create missing tiers in the tiers array\n for (uint256 i = _tiers.length; i < tier; i++) {\n _tiers.push(0);\n }\n\n // Ensure tier amount is not greater than next tier one (if next tier exists)\n if (tier != _tiers.length) {\n require(amount <= _tiers[tierIndex + 1], \"L35\");\n }\n\n // Ensure tier amount is not lower than previous tier one (if previous tier exists)\n if (tier != 1) {\n require(amount >= _tiers[tierIndex - 1], \"L36\");\n }\n\n // Set the new tier value\n _tiers[tierIndex] = amount;\n }\n\n /**\n * @dev Returns the amount of $LDY tokens that must be staked to be elligible to a given\n * staking tier.\n * @param tier The tier number (not its index in the array)\n * @return The amount of $LDY tokens to stake to be elligible to the tier\n */\n function getTier(uint256 tier) public view returns (uint256) {\n // Ensure the tier is > 0 (as it shouldn't be an index)\n require(tier > 0, \"L37\");\n\n // Ensure the staking tier exists\n require(tier <= _tiers.length, \"L38\");\n\n // Return the tier value\n return _tiers[tier - 1];\n }\n\n /**\n * @dev Returns the staking a given account is ellible to.\n * @param account The account to check the tier of\n * @return tier The tier number (not its index in the array)\n */\n function tierOf(address account) public view returns (uint256 tier) {\n // Retrieve user stake\n uint256 stakedAmount = stakeOf(account);\n\n // If first tier is not set or account is not elligible to it, return 0\n if (_tiers.length < 1 || stakedAmount < getTier(1)) return 0;\n\n // Else tier is at least equal to 1\n tier = 1;\n\n // Finally increment tier until there is no more tier or the staked amount doesn't fit in next one\n while (tier + 1 <= _tiers.length && stakedAmount >= getTier(tier + 1)) tier++;\n }\n}\n" - }, - "contracts/src/dev/Multicall3.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @title Multicall3\n/// @notice Aggregate results from multiple function calls\n/// @dev Multicall & Multicall2 backwards-compatible\n/// @dev Aggregate methods are marked `payable` to save 24 gas per call\n/// @author Michael Elliot \n/// @author Joshua Levine \n/// @author Nick Johnson \n/// @author Andreas Bigger \n/// @author Matt Solomon \ncontract Multicall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n /// @notice Backwards-compatible call aggregation with Multicall\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return returnData An array of bytes containing the responses\n function aggregate(\n Call[] calldata calls\n ) public payable returns (uint256 blockNumber, bytes[] memory returnData) {\n blockNumber = block.number;\n uint256 length = calls.length;\n returnData = new bytes[](length);\n Call calldata call;\n for (uint256 i = 0; i < length; ) {\n bool success;\n call = calls[i];\n (success, returnData[i]) = call.target.call(call.callData);\n require(success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls without requiring success\n /// @param requireSuccess If true, require all calls to succeed\n /// @param calls An array of Call structs\n /// @return returnData An array of Result structs\n function tryAggregate(\n bool requireSuccess,\n Call[] calldata calls\n ) public payable returns (Result[] memory returnData) {\n uint256 length = calls.length;\n returnData = new Result[](length);\n Call calldata call;\n for (uint256 i = 0; i < length; ) {\n Result memory result = returnData[i];\n call = calls[i];\n (result.success, result.returnData) = call.target.call(call.callData);\n if (requireSuccess) require(result.success, \"Multicall3: call failed\");\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function tryBlockAndAggregate(\n bool requireSuccess,\n Call[] calldata calls\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\n blockNumber = block.number;\n blockHash = blockhash(block.number);\n returnData = tryAggregate(requireSuccess, calls);\n }\n\n /// @notice Backwards-compatible with Multicall2\n /// @notice Aggregate calls and allow failures using tryAggregate\n /// @param calls An array of Call structs\n /// @return blockNumber The block number where the calls were executed\n /// @return blockHash The hash of the block where the calls were executed\n /// @return returnData An array of Result structs\n function blockAndAggregate(\n Call[] calldata calls\n ) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) {\n (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);\n }\n\n /// @notice Aggregate calls, ensuring each returns success if required\n /// @param calls An array of Call3 structs\n /// @return returnData An array of Result structs\n function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) {\n uint256 length = calls.length;\n returnData = new Result[](length);\n Call3 calldata calli;\n for (uint256 i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n (result.success, result.returnData) = calli.target.call(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x64)\n }\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Aggregate calls with a msg value\n /// @notice Reverts if msg.value is less than the sum of the call values\n /// @param calls An array of Call3Value structs\n /// @return returnData An array of Result structs\n function aggregate3Value(\n Call3Value[] calldata calls\n ) public payable returns (Result[] memory returnData) {\n uint256 valAccumulator;\n uint256 length = calls.length;\n returnData = new Result[](length);\n Call3Value calldata calli;\n for (uint256 i = 0; i < length; ) {\n Result memory result = returnData[i];\n calli = calls[i];\n uint256 val = calli.value;\n // Humanity will be a Type V Kardashev Civilization before this overflows - andreas\n // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256\n unchecked {\n valAccumulator += val;\n }\n (result.success, result.returnData) = calli.target.call{value: val}(calli.callData);\n assembly {\n // Revert if the call fails and failure is not allowed\n // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)`\n if iszero(or(calldataload(add(calli, 0x20)), mload(result))) {\n // set \"Error(string)\" signature: bytes32(bytes4(keccak256(\"Error(string)\")))\n mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n // set data offset\n mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n // set length of revert string\n mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017)\n // set revert string: bytes32(abi.encodePacked(\"Multicall3: call failed\"))\n mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000)\n revert(0x00, 0x84)\n }\n }\n unchecked {\n ++i;\n }\n }\n // Finally, make sure the msg.value = SUM(call[0...i].value)\n require(msg.value == valAccumulator, \"Multicall3: value mismatch\");\n }\n\n /// @notice Returns the block hash for the given block number\n /// @param blockNumber The block number\n function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {\n blockHash = blockhash(blockNumber);\n }\n\n /// @notice Returns the block number\n function getBlockNumber() public view returns (uint256 blockNumber) {\n blockNumber = block.number;\n }\n\n /// @notice Returns the block coinbase\n function getCurrentBlockCoinbase() public view returns (address coinbase) {\n coinbase = block.coinbase;\n }\n\n /// @notice Returns the block difficulty\n function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {\n difficulty = block.difficulty;\n }\n\n /// @notice Returns the block gas limit\n function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {\n gaslimit = block.gaslimit;\n }\n\n /// @notice Returns the block timestamp\n function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {\n timestamp = block.timestamp;\n }\n\n /// @notice Returns the (ETH) balance of a given address\n function getEthBalance(address addr) public view returns (uint256 balance) {\n balance = addr.balance;\n }\n\n /// @notice Returns the block hash of the last block\n function getLastBlockHash() public view returns (bytes32 blockHash) {\n unchecked {\n blockHash = blockhash(block.number - 1);\n }\n }\n\n /// @notice Gets the base fee of the given block\n /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain\n function getBasefee() public view returns (uint256 basefee) {\n basefee = block.basefee;\n }\n\n /// @notice Returns the chain id\n function getChainId() public view returns (uint256 chainid) {\n chainid = block.chainid;\n }\n}\n" - }, - "contracts/src/DummyLDYStaking.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title LDYStaking\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Replacement to the LDYStaking contract until the $LDY token is available and\n * the real LDYStaking can be deployed.\n *\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\n * one the LToken contract relies on.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LDYStaking is Ownable2Step {\n /**\n * @notice Holds a mapping of addresses that default to the highest staking tier.\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\n */\n mapping(address => bool) public highTierAccounts;\n\n /**\n * @notice Update high tier status of a given account.\n * @param account The account to update the high tier status of.\n */\n function setHighTierAccount(address account, bool status) external onlyOwner {\n highTierAccounts[account] = status;\n }\n\n /**\n * @dev Dummy tierOf() function that always return that the given account is not\n * ellgible to any LDY staking tier, except if the account is in the\n * defaultToHighestTier mapping.\n * @param account The account to check the tier of.\n */\n function tierOf(address account) public view returns (uint256 tier) {\n if (highTierAccounts[account]) return 3;\n return 0;\n }\n}\n" - }, - "contracts/src/GlobalBlacklist.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalBlacklist\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Maintains a global mapping of blacklisted accounts on-chain. All contracts\n * within the Ledgity Yield codebase reference this mapping to prevent access by\n * blacklisted accounts.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\n * and getter functions to easily check against this global blacklist.\n *\n * @dev For further details, see \"GlobalBlacklist\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Mapping of accounts to their blacklist status.\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\n */\n mapping(address => bool) private _list;\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Adds a given account to the blacklist.\n * @param account The account's address to be blacklisted.\n */\n function blacklist(address account) external onlyOwner {\n require(account != address(0), \"L20\");\n _list[account] = true;\n }\n\n /**\n * @notice Removes a given account from the blacklist.\n * @param account The account's address to be un-blacklisted.\n */\n function unBlacklist(address account) external onlyOwner {\n _list[account] = false;\n }\n\n /**\n * @notice Checks whether a given account is blacklisted.\n * @param account Address of the account to check.\n * @return 'true' if the account is blacklisted, 'false' otherwise\n */\n function isBlacklisted(address account) external view returns (bool) {\n // Gas optimization: Avoid accessing storage if account is the zero address\n // (e.g, during a mint or a burn of tokens)\n if (account == address(0)) return false;\n\n // Else, return current account's blacklist status\n return _list[account];\n }\n}\n" - }, - "contracts/src/GlobalOwner.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\n/**\n * @title GlobalOwner\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Maintains the address of a global owner account shared by all contracts of the\n * Ledgity Yield's codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\n * owner() function that retrieves the owner's address from this contract instead.\n *\n * @dev For further details, see \"GlobalOwner\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize() public initializer {\n __Ownable2Step_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n}\n" - }, - "contracts/src/GlobalPause.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalPause\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Maintains a global pause state shared by all contracts of the Ledgity Yield\n * codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\n * paused() function that retrieves the pause state from this contract instead.\n *\n * @dev For further details, see \"GlobalPause\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalPause is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n PausableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\n * but restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n}\n" - }, - "contracts/src/interfaces/ITransfersListener.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\ninterface ITransfersListener {\n function onLTokenTransfer(address from, address to, uint256 amount) external;\n}\n" - }, - "contracts/src/libs/APRHistory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n/**\n * @title APRHistory\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This library offers utilities to efficiently maintain on chain, the history of\n * an APR (Annual Percentage Rate). Each entry in this history is called a \"checkpoint\".\n *\n * @dev Intuition:\n * Each checkpoint in an APR history consists in two data:\n * - the creation timestamp\n * - the APR at that time\n *\n * Given that reads and writes to storage slots are among the most costly operations in\n * Solidity, this library provides a way to store those data on chain in a way that\n * minimizes the number of used storage slots.\n *\n * Instead of storing each checkpoint in a separate storage slot, this library\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\n *\n * @dev Definitions:\n * - Checkpoint: A record of an APR change\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\n * - History: A dynamic array of packs\n * - Reference: A storage pointer to a checkpoint in the APR history\n * - CheckpointData: An in-memory representation of a checkpoint data\n *\n * @dev Limitation: This library can accommodate APRs only up to 65.536%. This is however\n * sufficient for APR in LToken contract, which is expected to remain below 10%.\n *\n * @dev For further details, see \"APRHistory\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary APRHistory {\n /**\n * @notice Represents data of a checkpoint extracted from the on-chain history.\n * For on-chain representation see \"Pack\" struct.\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\n * @param timestamp Timestamp of the checkpoint's creation.\n */\n struct CheckpointData {\n uint16 aprUD7x3; // Allows up to 65.536%\n uint40 timestamp; // Supports dates up to 20/02/36812\n }\n\n /**\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\n * @param aprsUD7x3 Array of checkpoints' APRs.\n * @param timestamps Array of checkpoints' timestamps.\n * @param cursor Index of the next checkpoint to be written.\n */\n struct Pack {\n uint16[4] aprsUD7x3;\n uint40[4] timestamps;\n uint32 cursor;\n }\n\n /**\n * @notice Represents a storage pointer to a specific checkpoint in the history.\n * @param packIndex Index of the pack the checkpoint belongs to.\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\n */\n struct Reference {\n uint256 packIndex;\n uint32 cursorIndex;\n }\n\n /**\n * @notice Compares two checkpoints references.\n * @param ref1 The first reference to compare.\n * @param ref2 The second reference to compare.\n * @return Whether the two references points to the same checkpoint.\n */\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\n }\n\n /**\n * @notice Returns the reference of the checkpoint that should come right after the\n * referenced checkpoint in the APR history.\n * @param ref The reference to be incremented.\n * @return The incremented reference.\n */\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L1\");\n\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\n //\n // Else, return ref of next slot in current pack\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\n }\n\n /**\n * @notice Extracts checkpoint data from a given reference and in APR history.\n * @param self The APR history to extract the checkpoint from.\n * @param ref The reference of the checkpoint data to extract.\n * @return The extracted checkpoint's data.\n */\n function getDataFromReference(\n Pack[] storage self,\n Reference memory ref\n ) public view returns (CheckpointData memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L2\");\n\n // Ensure pack index of the given ref exists in history\n require(ref.packIndex < self.length, \"L3\");\n\n // Retrieve pack data from history\n Pack memory pack = self[ref.packIndex];\n\n // Ensure cursor index of the given ref has been written\n require(ref.cursorIndex < pack.cursor, \"L4\");\n\n // Build and return the checkpoint data\n return\n CheckpointData({\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\n timestamp: pack.timestamps[ref.cursorIndex]\n });\n }\n\n /**\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\n * @param self The history to extract the reference from.\n * @return The reference of the latest checkpoint.\n */\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\n // Ensure the given history is not empty\n require(self.length != 0, \"L5\");\n\n // Retrieve latest pack's index and cursor\n uint256 packIndex = self.length - 1;\n uint32 packCursor = self[packIndex].cursor;\n\n // If this is the first pack ever, ensure it is not empty\n if (packIndex == 0) require(packCursor != 0, \"L6\");\n\n // If the pack is empty, return ref of previous pack's latest slot\n if (packCursor == 0) return Reference(packIndex - 1, 3);\n //\n // Else, return ref of previous slot in current pack\n else return Reference(packIndex, packCursor - 1);\n }\n\n /**\n * @notice Appends a new empty pack to the end of the given APR history array.\n * @param self The APR history to append an empty to.\n */\n function newBlankPack(Pack[] storage self) internal {\n // If history is not empty, ensure the latest pack is full\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \"L7\");\n\n // Push a new blank pack to the history array\n self.push(\n Pack({\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\n cursor: 0\n })\n );\n }\n\n /**\n * @notice Write a new APR checkpoint at the end of the given history array.\n * @param self The array of packs to write the new checkpoint to.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\n // Determine the reference where the new checkpoint should be written\n Reference memory newRef = self.length == 0\n ? Reference(0, 0)\n : incrementReference(getLatestReference(self));\n\n // If pack to be written doesn't exist yet, push a new blank pack in history\n if (newRef.packIndex >= self.length) newBlankPack(self);\n\n // Retrieve the pack where the new checkpoint will be stored\n Pack memory pack = self[newRef.packIndex];\n\n // Add new checkpoint's data to the pack\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\n\n // Increment the pack's cursor\n pack.cursor++;\n\n // Write the updated pack in storage\n self[newRef.packIndex] = pack;\n }\n\n /**\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\n * @param self The history array to read APR from.\n * @return The latest checkpoint's APR.\n */\n function getAPR(Pack[] storage self) public view returns (uint16) {\n // Retrieve the latest checkpoint data\n Reference memory ref = getLatestReference(self);\n CheckpointData memory data = getDataFromReference(self, ref);\n\n // Return the latest checkpoint's APR\n return data.aprUD7x3;\n }\n}\n" - }, - "contracts/src/libs/SUD.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title SUD\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice SUD serves as an intermediary number format for calculations within this\n * codebase. It ensures consistency and reduces precision losses. This library\n * facilitates conversions between various number formats and the SUD format.\n *\n * @dev Intuition:\n * This codebase employs UD (unsigned decimal fixed-point numbers) format to represent\n * both percentage rates and tokens amounts.\n *\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\n * the decimals() value of the involved tokens.\n *\n * Three challenges arise from this:\n * 1) To compute values together, it's essential that they are in the same format\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\n * precision loss (because division shrinks). A common approach is to scale up and\n * down values by a few decimals before and after performing calculations.\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\n * be shrinked in case token's decimals number is in [0, 2].\n *\n * To address these challenges, this library provides the SUD format, which acts as a\n * consistent and scaled intermediate format to perform calculations on.\n *\n * SUD is an acronym for either \"Scaled UD\" or \"Safe UD\".\n *\n * @dev Definitions:\n * - Integer: A number without fractional part, e.g., block.timestamp\n * - UD: A decimal unsigned fixed-point number. The \"UD\" notation is inspired from\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\n * - Amount: An UD with an unknown (at writing time) repartition of digits between\n * integral and fractional parts. Represents a token amount.\n * - Rate: An UD with 7 integral digits and 3 fractional ones (a.k.a UD7x3).\n * Represents a percentage rate.\n * - SUD: An UD with 3 more decimals than the involved rate or amount with the highest\n * decimals number. As rates are represented by UD7x3, a SUD number has at least 6\n * decimals (3+3) and so ranges from UD71x6 to UD0x77 formats.\n * Used as an intermediate format to perform calculations.\n *\n * @dev This library provides utilities to perform the following conversions:\n * - Amount <--> SUD\n * - Rate (UD7x3) <--> SUD\n * - Integer <--> SUD\n *\n * @dev Why scaling by 3 decimals?\n * - It provides an adequate degree of precision for this codebase,\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\n * the involved token's decimal number.\n *\n * @dev Optimization note: The functions of this library are not set to external because\n * incorporating them directly into contracts is more gas-efficient. Given their minimal\n * size and frequent usage in the InvestUpgradeable, LDYStaking, and LToken contracts,\n * any bytecode savings from making them external are negated by the additional bytecode\n * required for external calls to this library.\n * The can be observed by comparing the output of `pnpm cc:size` when those functions's\n * visibility is set to external or internal.\n *\n * @dev Precision note: While this library mitigates precision loss during calculations\n * on UD numbers, it's important to note that tokens with lower decimal counts and supply\n * inherently suffer more from precision loss. Conversely, tokens with higher decimal\n * counts and supply will experience less precision loss.\n *\n * @dev For further details, see \"SUD\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary SUD {\n /**\n * @notice Retrieves decimals number of the given ERC20 contract address.\n * @param tokenAddress The address to retrieve decimals number from.\n * @return decimals The decimals number of the given ERC20 contract address.\n */\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\n }\n\n /**\n * @notice Convert a given token amount into SUD format.\n * @param nAmount The token amount to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The amount in SUD format\n */\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\n\n // Else return a number with decimals+3 fractional digits\n return nAmount * 10 ** 3;\n }\n\n /**\n * @notice Convert a given SUD number into token amount format.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nAmount The number in amount format\n */\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** 3;\n }\n\n /**\n * @notice Converts a given UD7x3 rate into SUD format.\n * @param nUD7x3 The UD7x3 rate to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The rate in SUD format.\n */\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nUD7x3 * 10 ** 3;\n\n // Else, return a number with decimals+3 fractional digits\n return nUD7x3 * 10 ** decimals;\n }\n\n /**\n * @notice Converts a given SUD number into a UD7x3 rate.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nUD7x3 The number in UD7x3 rate format.\n */\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 3;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** decimals;\n }\n\n /**\n * @notice Converts a given integer into SUD format.\n * @param n The integer to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The integer in SUD format.\n */\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return n * 10 ** 6;\n\n // Else, return a number with decimals+3 fractional digits\n return n * 10 ** (decimals + 3);\n }\n\n /**\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return n The SUD number as an integer.\n */\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 6;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** (decimals + 3);\n }\n}\n" - }, - "contracts/src/LToken.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\n// Contracts\nimport {ERC20WrapperUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\";\nimport \"./abstracts/base/ERC20BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"./abstracts/InvestUpgradeable.sol\";\nimport {LDYStaking} from \"./DummyLDYStaking.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {SUD} from \"./libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport {ITransfersListener} from \"./interfaces/ITransfersListener.sol\";\n\n/**\n * @title LToken\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e,\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\n * the form of additional L-Tokens, which are auto-compounded over time.\n *\n * @dev Definitions:\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\n * - Instant: Processed immediately.\n * - Requested: Queued for later processing.\n * - Big Requested: A requested withdrawal exceeding half of the retention rate.\n * - (Withdrawal) queue: An list of all requested withdrawals sorted by priority.\n * - Request ID: The index of a withdrawal request in the queue array.\n * - Retention rate: Maximum fraction of underlying tokens TVL that the contract can retain.\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\n * expected ways and are so considered as safe to use by the contract.\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\n * processing.\n *\n * Note that words between parenthesis are sometimes omitted for brevity.\n *\n * @dev Security: This contract can safely receive funds immediately after initialization.\n * (i.e., there is no way for funds to be sent to non-owned addresses). It is however\n * recommended to replace ASAP owner and fund wallets by multi-sig wallets.\n *\n * @dev For further details, see \"LToken\" section of whitepaper.\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n * @custom:security-contact security@ledgity.com\n */\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @dev Represents type of actions triggering ActivityEvent events.\n enum Action {\n Deposit,\n Withdraw\n }\n\n /// @dev Represents different status of actions triggering ActivityEvent events.\n enum Status {\n Queued,\n Cancelled,\n Success,\n Moved\n }\n\n /**\n * @notice Represents a withdrawal request in the queue.\n * @dev A request fits in a single storage slot (32 bytes).\n * @param account The account that initiated the request.\n * @param amount The amount of underlying tokens requested.\n */\n struct WithdrawalRequest {\n address account; // 20 bytes\n uint96 amount; // 12 bytes\n }\n\n /// @notice Upper limit of retention rate.\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\n\n /// @notice Used in activity events to represent the absence of request ID.\n int256 private constant NO_ID = -1;\n\n /// @notice Holds a reference to the LDYStaking contract.\n LDYStaking public ldyStaking;\n\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\n address payable public withdrawer;\n\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\n address public fund;\n\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\n uint32 public feesRateUD7x3;\n\n /// @notice Holds the retention rate in UD7x3 format.\n uint32 public retentionRateUD7x3;\n\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\n uint256 public unclaimedFees;\n\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\n uint256 public totalQueued;\n\n /**\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\n */\n uint256 public usableUnderlyings;\n\n /// @notice Holds an ordered list of active withdrawal requests.\n WithdrawalRequest[] public withdrawalQueue;\n\n /// @notice Holds the index of the next withdrawal request to process in the queue.\n uint256 public withdrawalQueueCursor;\n\n /**\n * @notice Holds a list of all currently frozen withdrawal requests.\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\n * it from blocking the queue.\n */\n WithdrawalRequest[] public frozenRequests;\n\n /**\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\n */\n ITransfersListener[] public transfersListeners;\n\n /**\n * @notice Emitted to inform listeners about a change in the contract's TVL.\n * @dev TVL = realTotalSupply()\n * @param newTVL The new TVL of the contract.\n */\n event TVLChangeEvent(uint256 newTVL);\n\n /**\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\n * @param account The account involved in the activity.\n * @param action The type of activity.\n * @param amount The amount of underlying tokens involved in the activity.\n * @param newStatus The new status of the activity.\n * @param newId The new ID of the request if it has been moved in the queue.\n */\n event ActivityEvent(\n int256 indexed id,\n address indexed account,\n Action indexed action,\n uint256 amount,\n uint256 amountAfterFees,\n Status newStatus,\n int256 newId\n );\n\n /**\n * @notice Emitted to inform listeners that some rewards have been minted.\n * @param account The account that received the rewards.\n * @param balanceBefore The balance of the account before the minting.\n * @param rewards The amount of minted rewards.\n */\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\n\n /// @notice Reverts if the function caller is not the withdrawer wallet.\n modifier onlyWithdrawer() {\n require(_msgSender() == withdrawer, \"L39\");\n _;\n }\n\n /// @notice Reverts if the function caller is not the fund wallet.\n modifier onlyFund() {\n require(_msgSender() == fund, \"L40\");\n _;\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyStaking_,\n address underlyingToken\n ) public initializer {\n // Initialize ERC20 base.\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\n __ERC20Base_init(\n globalOwner_,\n globalPause_,\n globalBlacklist_,\n string(abi.encodePacked(\"Ledgity \", underlyingSymbol)),\n string(abi.encodePacked(\"L\", underlyingSymbol))\n );\n\n // IMPORTANT: Below calls must not be restricted to owner at any point.\n // This is because the GlobalOwner contract may not be a fresh one, and so\n // the contract deployer may not be the owner anymore after ERC20Base init.\n\n // Initialize other parents contracts.\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\n __Invest_init_unchained(address(this));\n\n // Set LDYStaking contract\n ldyStaking = LDYStaking(ldyStaking_);\n\n // Set initial withdrawal fees rate to 0.3%\n feesRateUD7x3 = 300;\n\n // Set initial retention rate to 10%\n retentionRateUD7x3 = 10_000;\n\n // Default withdrawer and fund wallet to contract owner address. This prevents\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\n withdrawer = payable(owner());\n fund = payable(owner());\n }\n\n /**\n * @notice Required override of decimals() which is implemented by both\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\n * decimals amount of the underlying stablecoin token.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function decimals()\n public\n view\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\n returns (uint8)\n {\n return ERC20WrapperUpgradeable.decimals();\n }\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @notice Updates the current withdrawal fee rate.\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\n */\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\n feesRateUD7x3 = feesRateUD7x3_;\n }\n\n /**\n * @notice Updates the current underlying token retention rate.\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\n * deposited assets will ever be exposed in this contract (reduces attack surface).\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\n */\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \"L41\");\n retentionRateUD7x3 = retentionRateUD7x3_;\n }\n\n /**\n * @notice Updates the address of LDYStaking contract.\n * @param ldyStakingAddress The address of the new LDYStaking contract.\n */\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\n ldyStaking = LDYStaking(ldyStakingAddress);\n }\n\n /**\n * @notice Updates the address of the withdrawer wallet.\n * @param withdrawer_ The address of the new withdrawer wallet.\n */\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\n // Ensure address is not the zero address (pre-processing fees would be lost else)\n require(withdrawer_ != address(0), \"L63\");\n\n // Set new withdrawer wallet's address\n withdrawer = withdrawer_;\n }\n\n /**\n * @notice Updates the address of the fund wallet.\n * @param fund_ The address of the new fund wallet.\n */\n function setFund(address payable fund_) public onlyOwner {\n // Ensure address is not the zero address (deposited tokens would be lost else)\n require(fund_ != address(0), \"L64\");\n\n // Set new fund wallet's address\n fund = fund_;\n }\n\n /**\n * @notice Adds a new contract to the L-Token transfers list.\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\n * specified contract will be called.\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\n * contracts that are not owned by the Ledgity team.\n * @param listenerContract The address of the new transfers listener contract.\n */\n function listenToTransfers(address listenerContract) public onlyOwner {\n transfersListeners.push(ITransfersListener(listenerContract));\n }\n\n /**\n * @notice Removes a contract from the L-Token transfers list.\n * @dev The onLTokenTransfer() function of the specified contract will not be called\n * anymore each time a L-Token transfer occurs.\n * @param listenerContract The address of the listener contract.\n */\n function unlistenToTransfers(address listenerContract) public onlyOwner {\n // Find index of listener contract in transferListeners array\n int256 index = -1;\n uint256 transfersListenersLength = transfersListeners.length;\n for (uint256 i = 0; i < transfersListenersLength; i++) {\n if (address(transfersListeners[i]) == listenerContract) {\n index = int256(i);\n break;\n }\n }\n\n // Revert if given contract wasn't listening to transfers\n require(index > -1, \"L42\");\n\n // Else, remove transfers listener contract from listeners array\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\n transfersListeners.pop();\n }\n\n /**\n * @notice Retrieves the amount of given account's not yet minted rewards.\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\n * context of LToken, this function returns the amount of rewards that have not been\n * distributed/minted yet to the specified account.\n * @dev This is particularly useful for off-chain services to display charts and\n * statistics, as seen in the Ledgity Yield's frontend.\n * @param account The account to check the unminted rewards of.\n * @return The amount of account's unminted rewards.\n */\n function unmintedRewardsOf(address account) public view returns (uint256) {\n return _rewardsOf(account, true);\n }\n\n /**\n * @notice Retrieves the \"real\" balance of an account, i.e., excluding its not yet\n * minted/distributed rewards.\n * @param account The account to check the real balance of.\n * @return The real balance of the account.\n */\n function realBalanceOf(address account) public view returns (uint256) {\n return super.balanceOf(account);\n }\n\n /**\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\n * not been yet minted to the specified account.\n * @param account The account to check the total balance of.\n * @return The total balance of the account.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return realBalanceOf(account) + unmintedRewardsOf(account);\n }\n\n /**\n * @notice Returns the \"real\" amount of existing L-Tokens, i.e., excluding not yet\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\n * @return The real total supply of L-Tokens.\n */\n function realTotalSupply() public view returns (uint256) {\n return super.totalSupply();\n }\n\n /**\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\n * fees and L-Tokens currently in the withdrawal queue.\n * @return The total supply of L-Tokens.\n */\n function totalSupply() public view override returns (uint256) {\n return realTotalSupply() + totalQueued + unclaimedFees;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address.\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\n * token from being the underlying token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the underlying token\n require(tokenAddress != address(underlying()), \"L43\");\n\n // Proceed to recovery\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @notice Recovers underlying tokens accidentally sent to the contract.\n * @dev To prevent owner from being able to drain the contract, this function only\n * allows recovering \"unusable\" underlying tokens, i.e., tokens that have not been\n * sent through fund() or deposit() functions.\n */\n function recoverUnderlying() external onlyOwner {\n // Compute the recoverable amount by taking the difference between the contract's\n // balance and the amount of usable underlying tokens\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\n\n // Revert if there is nothing to recover\n require(recoverableAmount > 0, \"L44\");\n\n // Else, proceed to underlying tokens recovery\n super.recoverERC20(address(underlying()), recoverableAmount);\n }\n\n /**\n * @notice Retrieves the amount of underlying tokens invested by the given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\n * LToken contract, the investment of an account is equal to its real balance.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return realBalanceOf(account);\n }\n\n /**\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract so\n * it can distribute rewards to accounts before each period reset.\n * @dev InvestUpgradeable contract already ensure that amount > 0.\n * @inheritdoc InvestUpgradeable\n */\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\n // Inform listeners of the rewards minting\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\n\n // Mint L-Tokens rewards to account\n _mint(account, amount);\n\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\n return true;\n }\n\n /**\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\n * called each time an account's balance is going to change.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\n * @inheritdoc ERC20BaseUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\n\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\n if (from != address(0)) _beforeInvestmentChange(from, true);\n if (to != address(0)) _beforeInvestmentChange(to, true);\n }\n\n /**\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\n * transfers listeners.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already checked in _beforeTokenTransfer().\n * @inheritdoc ERC20Upgradeable\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\n super._afterTokenTransfer(from, to, amount);\n\n // If some L-Token have been burned/minted, inform listeners of a TVL change\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\n\n // Trigger onLTokenTransfer() functions of all the transfers listeners\n for (uint256 i = 0; i < transfersListeners.length; i++) {\n transfersListeners[i].onLTokenTransfer(from, to, amount);\n }\n }\n\n /**\n * @notice Computes the maximum amount of underlying tokens that should be retained\n * by the contract (based on retention rate).\n * @return amount The expected amount of retained underlying tokens.\n */\n function getExpectedRetained() public view returns (uint256 amount) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert totalSupply and retentionRate to SUD\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\n\n // Compute and return expected retained amount\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(expectedRetainedSUD, d);\n }\n\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\n function _transferExceedingToFund() internal {\n // Retrieve the expected amount retained\n uint256 expectedRetained = getExpectedRetained();\n\n // If usable underlyings are less than or equal to expected retained, return\n if (usableUnderlyings <= expectedRetained) return;\n\n // Else, exceeding amount is equal to difference between those values\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= exceedingAmount;\n\n // Transfer the exceeding amount to the fund wallet\n underlying().safeTransfer(fund, exceedingAmount);\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L45\");\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\n * Use deposit() function instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L46\");\n }\n\n /**\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\n * @param amount The amount of underlying tokens to deposit.\n */\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough underlying tokens to deposit\n require(underlying().balanceOf(_msgSender()) >= amount, \"L47\");\n\n // Update usable underlyings balance accordingly\n usableUnderlyings += amount;\n\n // Inform listeners of the deposit activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Deposit,\n amount,\n amount,\n Status.Success,\n NO_ID\n );\n\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\n super.depositFor(_msgSender(), amount);\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\n * given amount.\n * @param account The account initiating the withdrawal.\n * @param amount The amount of the withdrawal.\n */\n function getWithdrawnAmountAndFees(\n address account,\n uint256 amount\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\n // If the account is eligible to staking tier 2, no fees are applied\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\n\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert amount and fees rate to SUD\n uint256 amountSUD = SUD.fromAmount(amount, d);\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\n\n // Compute fees and withdrawn amount (initial amount minus fees)\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\n fees = SUD.toAmount(feesSUD, d);\n withdrawnAmount = amount - fees;\n }\n\n /**\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\n * enough underlying tokens to cover the withdrawal.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestWithdrawal() function otherwise.\n * @param amount The amount L-Tokens to withdraw.\n */\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L48\");\n\n // Can the contract cover this withdrawal plus all already queued requests?\n bool cond1 = totalQueued + amount <= usableUnderlyings;\n\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\n\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\n if (!(cond1 || cond2)) revert(\"L49\");\n\n // Else, retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\n\n // Increase unclaimed fees amount accordingly\n unclaimedFees += fees;\n\n // Decrease usable underlyings balance accordingly\n usableUnderlyings -= withdrawnAmount;\n\n // Inform listeners of this instant withdrawal activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Withdraw,\n amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Burn withdrawal fees from the account\n _burn(_msgSender(), fees);\n\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\n super.withdrawTo(_msgSender(), withdrawnAmount);\n }\n\n /**\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\n * amount of underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n * @param amount The amount L-Tokens to withdraw.\n */\n function requestWithdrawal(\n uint256 amount\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L53\");\n\n // Ensure the requested amount doesn't overflow uint96\n require(amount <= type(uint96).max, \"L54\");\n\n // Ensure the sender attached the pre-paid processing gas fees\n require(msg.value == 0.003 * 10 ** 18, \"L55\");\n\n // Create withdrawal request data\n WithdrawalRequest memory request = WithdrawalRequest({\n account: _msgSender(),\n amount: uint96(amount)\n });\n\n // Will hold the request ID\n uint256 requestId;\n\n // Append request to the withdrawal queue:\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\n withdrawalQueueCursor--;\n requestId = withdrawalQueueCursor;\n withdrawalQueue[requestId] = request;\n }\n // - At the end else\n else {\n withdrawalQueue.push(request);\n requestId = withdrawalQueue.length - 1;\n }\n\n // Increase total amount queued accordingly\n totalQueued += amount;\n\n // Inform listeners of this new queued withdrawal activity event\n emit ActivityEvent(\n int256(requestId),\n _msgSender(),\n Action.Withdraw,\n amount,\n amount,\n Status.Queued,\n NO_ID\n );\n\n // Burn withdrawal L-Tokens amount from account's balance\n _burn(_msgSender(), amount);\n\n // Forward pre-paid processing gas fees to the withdrawer wallet\n (bool sent, ) = withdrawer.call{value: msg.value}(\"\");\n require(sent, \"L56\");\n }\n\n /**\n * @notice Processes queued withdrawal requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n * @dev For further details, see \"LToken > Withdrawals\" section of whitepaper.\n */\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\n // Accumulators variables, will be written on-chain after the loop\n uint256 cumulatedFees = 0;\n uint256 cumulatedWithdrawnAmount = 0;\n uint256 nextRequestId = withdrawalQueueCursor;\n\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\n // requests are increasing the queue length when moved at the end of the queue.\n uint256 queueLength = withdrawalQueue.length;\n\n // Iterate over requests to be processed\n while (nextRequestId < queueLength) {\n // Stop processing requests if there is not enough gas left to continue the\n // loop and properly end the function call. This prevents an attacker from\n // blocking the withdrawal processing by creating a ton of tiny requests so\n // this function call cannot fit anymore in block gas limit.\n if (gasleft() < 45000) break;\n\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\n\n // Skip empty request (processed big requests or cancelled requests)\n if (request.account == address(0)) {}\n //\n // If account has been blacklisted since request emission\n else if (isBlacklisted(request.account)) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request in the frozen requests list\n frozenRequests.push(request);\n }\n //\n // Or if request is a big request, move it at the end of the queue for now.\n // This request will be processed manually later using processBigQueuedRequest()\n else if (request.amount > getExpectedRetained() / 2) {\n // Inform listeners of this queued request being moved at the end of the queue\n emit ActivityEvent(\n int256(nextRequestId),\n _msgSender(),\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Moved,\n int256(withdrawalQueue.length)\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request at the end of the queue\n withdrawalQueue.push(request);\n }\n //\n // Else, continue request processing\n else {\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Break if the contract doesn't hold enough funds to cover the request\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\n\n // Accumulate fees and withdrawn amount\n cumulatedFees += fees;\n cumulatedWithdrawnAmount += withdrawnAmount;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(nextRequestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Transfer underlying tokens to account. Burning L-Tokens is not required\n // as equestWithdrawal() already did it.\n // Security note: Re-entrancy warning are disabled as the request has\n // just been deleted from the queue, it will so be skipped if trying to\n // process it again.\n // slither-disable-next-line reentrancy-no-eth\n underlying().safeTransfer(request.account, withdrawnAmount);\n }\n\n // Increment next request ID\n nextRequestId++;\n }\n\n // Increase unclaimed fees by the amount of cumulated fees\n unclaimedFees += cumulatedFees;\n\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\n usableUnderlyings -= cumulatedWithdrawnAmount;\n\n // Decrease total amount queued by the cumulated amount requested\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\n\n // Update new queue cursor\n withdrawalQueueCursor = nextRequestId;\n\n // Retention rate cannot exceeds as the withdrawal decreases both usable\n // underlyings and expected retained amounts by the same number and as the\n // expected retained amount is a subset of usable underlyings amount.\n }\n\n /**\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\n * the retention rate).\n * @dev In contrast to non-big requests processing, this function will uses to fund\n * wallet's balance to fill the request. This allows processing requests that are\n * greater than retention rate without having to exceed this rate on the contract.\n * @param requestId The ID of the big request to process.\n */\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure the request is active\n require(request.account != address(0), \"L66\");\n\n // Ensure the request emitter has not been blacklisted since request emission\n require(!isBlacklisted(request.account), \"L50\");\n\n // Ensure this is indeed a big request\n require(request.amount > getExpectedRetained() / 2, \"L51\");\n\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\n uint256 fundBalance = underlying().balanceOf(fund);\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \"L52\");\n\n // Increase amount of unclaimed fees accordingly\n unclaimedFees += fees;\n\n // Decrease total queued amount by request amount\n totalQueued -= request.amount;\n\n // Increment queue cursor if request was the next request to be processed\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[requestId];\n\n // If fund wallet's balance can cover request, rely on it only\n if (withdrawnAmount <= fundBalance) {\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\n }\n // Else, cover request from both fund wallet and contract balances\n else {\n // Compute amount missing from fund wallet to cover request\n uint256 missingAmount = withdrawnAmount - fundBalance;\n\n // Decrease usable amount of underlying tokens accordingly\n usableUnderlyings -= missingAmount;\n\n // Transfer entire fund balance to request's emitter\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\n\n // Transfer missing amount from contract balance to request emitter\n underlying().safeTransfer(request.account, missingAmount);\n }\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Cancels a given withdrawal request. The request emitter receive back its\n * L-Tokens and no fees will be charged.\n * @param requestId The ID of the withdrawal request to cancel.\n */\n function cancelWithdrawalRequest(\n uint256 requestId\n ) public whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure request belongs to caller\n require(_msgSender() == request.account, \"L57\");\n\n // Decrease total amount queued accordingly\n totalQueued -= request.amount;\n\n // Delete the withdrawal request from queue\n delete withdrawalQueue[requestId];\n\n // Inform listeners of this cancelled withdrawal request activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Cancelled,\n NO_ID\n );\n\n // Mint back L-Tokens to account\n _mint(request.account, uint256(request.amount));\n }\n\n /**\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\n * whenever those are required to fulfill some withdrawal requests.\n * @dev The function will revert if repatriated amount makes the contract exceeding\n * the retention rate.\n * @param amount The amount of underlying tokens to repatriate.\n */\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\n // Ensure the fund wallet has enough funds to repatriate\n require(amount <= underlying().balanceOf(fund), \"L58\");\n\n // Calculate new contract usable balance\n uint256 newBalance = usableUnderlyings + amount;\n\n // Ensure the new balance doesn't exceed the retention rate\n require(newBalance <= getExpectedRetained(), \"L59\");\n\n // Increase usable underlyings amount by repatriated amount\n usableUnderlyings += amount;\n\n // Transfer amount from fund wallet to contract\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /// @notice Used by owner to claim fees generated from successful withdrawals.\n function claimFees() external onlyOwner {\n // Ensure there are some fees to claim\n require(unclaimedFees > 0, \"L60\");\n\n // Ensure the contract holds enough underlying tokens to cover fees\n require(usableUnderlyings >= unclaimedFees, \"L61\");\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= unclaimedFees;\n\n // Store fees amount in memory and reset unclaimed fees amount\n uint256 fees = unclaimedFees;\n unclaimedFees = 0;\n\n // Transfer unclaimed fees to owner\n underlying().safeTransfer(owner(), fees);\n }\n}\n" - }, - "contracts/src/LTokenSignaler.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title LTokenSignaler\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Used to inform subgraph from the existence of a new L-Token contract. Once\n * signaled, a L-Token it will start being indexed.\n *\n * @dev Signal are ignored by the subgraph if the L-Token is already known by it.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LTokenSignaler is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Emitted to inform subgraph of the existence of a new L-Token contract.\n * @param lTokenAddress The address of the L-Token contract to signal.\n */\n event LTokenSignalEvent(address indexed lTokenAddress);\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Signals a LToken contract to the TheGraph subgraph of the current chain.\n * @param lTokenAddress The address of the LToken contract to signal.\n */\n function signalLToken(address lTokenAddress) external onlyOwner {\n // Signal the LToken contract\n emit LTokenSignalEvent(lTokenAddress);\n }\n}\n" - }, - "contracts/src/PreMining.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.18;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {LToken} from \"./LToken.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\n/**\n * @title PreMining\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n\n * @notice PreMining pool contract, allowing accounts to lock underlying tokens in a \n * pre-defined L-Token contract, over a given duration (in months), in exchange of \n * vested LDY rewards.\n * \n * @dev Intuition\n * \n * Lifecycle of a lockdrop pool is composed by 3 main phases:\n * 1) Deposit: During this phase, users can lock their underlying tokens.\n * 2) Claim: During this phase, users can claim their LDY rewards.\n * 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract.\n * \n * Transitioning between two phases is manually triggered by contract's owner.\n * To ensure fair usage of this power and prevent potential misuse:\n * - the Recovery phase cannot start before 3 months after the end of rewards vesting,\n * - the Recovery phase cannot start before 3 months after the maximum lock end.\n * \n * Finally, note that this contract proxies main L-Token contract's functions:\n * - lock() --> deposit()\n * - instantUnlock() --> instantWithdrawal()\n * - requestUnlock() --> requestWithdrawal()\n * This design enables users to interact with the PreMining contract in a similar fashion\n * to the L-Token contract.\n * \n * @dev Definitions:\n * - Locker: An account that has locked underlying tokens in the pool.\n * \n * @custom:security-contact security@ledgity.com\n */\ncontract PreMining is Ownable2Step, Pausable {\n using SafeERC20 for IERC20;\n\n /**\n * @notice Represents the lock information of an account.\n * @param amount Amount of underlying tokens locked.\n * @param duration Duration of the lock (in months).\n * @param hasUnlocked Whether the account has unlocked its locked tokens.\n * @param claimedRewards Amount of LDY rewards already claimed.\n * @param lockEndTimestamp Timestamp at which the account's lock ends.\n */\n struct AccountLock {\n uint240 amount;\n uint8 duration;\n bool hasUnlocked;\n uint216 claimedRewards;\n uint40 lockEndTimestamp;\n }\n\n /// @notice Holds the amount of LDY to be distributed to lockers.\n uint256 public immutable maxDistributedLDY;\n\n /// @notice Holds the maximum total amount of L-Tokens that can be locked.\n uint256 public immutable lockedHardCap;\n\n /// @notice Holds the minimum possible lock duration (in months).\n uint8 public immutable minLockDuration;\n\n /// @notice Holds the maximum possible lock duration (in months).\n uint8 public immutable maxLockDuration;\n\n /// @notice Holds the duration of LDY rewards vesting (in months).\n uint8 public immutable vestingDuration;\n\n /// @notice Holds a reference to the locked L-Token contract.\n LToken public immutable lToken;\n\n /// @notice Holds a reference to the L-Token underlying stablecoin.\n IERC20 public immutable underlyingToken;\n\n /// @notice Holds the max pool weight.\n uint256 public immutable maxWeight;\n\n /// @notice Holds a reference to the LDY token contract.\n IERC20 public ldyToken;\n\n /// @notice Holds lockers' participations informations.\n mapping(address => AccountLock) public accountsLocks;\n\n /// @notice Holds the total amount of locked underlying tokens.\n uint256 public totalLocked;\n\n /// @notice Holds whether the Deposit phase has ended.\n bool public hasDepositPhaseEnded;\n\n /// @notice Holds whether the Claim phase has started.\n bool public hasClaimPhaseStarted;\n\n /// @notice Holds whether the Recovery phase has started.\n bool public hasRecoveryPhaseStarted;\n\n /// @notice Holds the timestamp at which the Claim phase started.\n uint256 public claimPhaseStartTimestamp;\n\n /// @notice Holds an ordered queue of accounts that requested to unlock their tokens.\n address[] public unlockRequests;\n\n /// @notice Holds the index of the first request in the queue (a.k.a, next one to be processed).\n uint256 public unlockRequestsCursor;\n\n /// @notice Emitted to inform about a new lock/deposit.\n event Lock(address indexed account, uint256 amount, uint8 duration);\n\n /// @notice Top-level checks and code shared by both unlock functions.\n modifier safeUnlock() {\n // Ensure that the account's lock has ended\n require(accountsLocks[msg.sender].lockEndTimestamp <= block.timestamp, \"L68\");\n\n // Ensure the account hasn't already unlocked its tokens\n require(!accountsLocks[msg.sender].hasUnlocked, \"L69\");\n\n // Ensure the account has something to unlock\n require(accountsLocks[msg.sender].amount > 0, \"L70\");\n\n // Indicate that account has unlocked its tokens\n accountsLocks[msg.sender].hasUnlocked = true;\n _;\n }\n\n /**\n * @notice This constructor function etches the lockdrop terms in immutable states.\n * Ensuring that those terms cannot be modified after deployment.\n * @param lTokenAddress_ Address of the L-Token contract to use.\n * @param maxDistributedLDY_ Amount of LDY to be distributed to lockers.\n * @param lockedHardCap_ Maximum total amount of L-Tokens that can be locked.\n * @param minLockDuration_ Minimum possible lock duration (in months).\n * @param maxLockDuration_ Maximum possible lock duration (in months).\n * @param vestingDuration_ Duration of LDY rewards vesting (in months).\n */\n constructor(\n address lTokenAddress_,\n uint256 maxDistributedLDY_,\n uint256 lockedHardCap_,\n uint8 minLockDuration_,\n uint8 maxLockDuration_,\n uint8 vestingDuration_\n ) {\n // Ensure minLockDuration is at least 1 month\n require(minLockDuration_ >= 1, \"L72\");\n\n // Ensure minLockDuration is not greater than maxLockDuration\n require(minLockDuration_ <= maxLockDuration_, \"L73\");\n\n // Set immutable states\n lToken = LToken(lTokenAddress_);\n underlyingToken = IERC20(address(lToken.underlying()));\n lockedHardCap = lockedHardCap_;\n maxDistributedLDY = maxDistributedLDY_;\n minLockDuration = minLockDuration_;\n maxLockDuration = maxLockDuration_;\n vestingDuration = vestingDuration_;\n maxWeight = lockedHardCap * uint256(maxLockDuration);\n }\n\n /**\n * @notice Public implementation of Pausable's pausing and unpausing functions, but\n * restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Updates the LDY token contract address.\n * @dev As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE,\n * this function allows the contract's owner to set the LDY token address once it\n * becomes available.\n * @param ldyTokenAddress Address of the LDY token contract.\n */\n function setLDYToken(address ldyTokenAddress) external onlyOwner {\n // Prevent owner from changing the LDY address after Claim phase has started\n require(!hasClaimPhaseStarted, \"L74\");\n\n // Set LDY token address\n ldyToken = IERC20(ldyTokenAddress);\n }\n\n /**\n * @notice Closes the Deposit phase. After calling this function, account won't be\n * able to lock additional underlying tokens anymore.\n */\n function endDepositPhase() external onlyOwner {\n hasDepositPhaseEnded = true;\n }\n\n /**\n * @notice Opens the Claim phase. After calling this function, lockers will be able\n * to start claiming their LDY rewards.\n */\n function startClaimPhase() external onlyOwner {\n // Ensure Claim phase has not already started\n require(!hasClaimPhaseStarted, \"L76\");\n\n // Ensure that LDY token address is available\n require(address(ldyToken) != address(0), \"L77\");\n\n // Set Claim phase as started and store the start timestamp\n hasClaimPhaseStarted = true;\n claimPhaseStartTimestamp = block.timestamp;\n }\n\n /**\n * @notice Opens the Recovery phase. After calling this function, the contract owner\n * will be able to recover remaining ERC20 tokens on the contract.\n * Note that this won't close the Claim phase and lockers will still be able to claim\n * their LDY rewards.\n */\n function startRecoveryPhase() external onlyOwner {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L79\");\n\n // Compute some durations in seconds\n uint256 threeMonthsInSecond = 3 * 30 days;\n uint256 vestingInSecond = uint256(vestingDuration) * 30 days;\n uint256 maxLockInSecond = uint256(maxLockDuration) * 30 days;\n\n // Compute timestamp of vesting end + 3 months\n uint256 afterVestingTimestamp = claimPhaseStartTimestamp +\n vestingInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the end of reward vesting\n // This prevents owner from recovering LDY before lockers can claim their rewards\n require(block.timestamp >= afterVestingTimestamp, \"L80\");\n\n // Compute end of maximum lock + 3 months\n // Note that claimPhaseStartTimestamp is used for simplicity even if it can exist a time\n // span between Deposit and Claim phases.\n uint256 afterMaxLockTimestamp = claimPhaseStartTimestamp +\n maxLockInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the maximum lock end\n // This prevents owner from recovering underlying tokens before lockers can unlock those\n require(block.timestamp >= afterMaxLockTimestamp, \"L81\");\n\n // Set recovery phase as started\n hasRecoveryPhaseStarted = true;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address. Will revert if\n * recovery phase has not started yet or if the contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\n // Ensure recovery phase has started\n require(hasRecoveryPhaseStarted, \"L82\");\n\n // Create a reference to token's contract\n IERC20 tokenContract = IERC20(tokenAddress);\n\n // Ensure there is enough tokens to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L83\");\n\n // Transfer the recovered token amount to the sender (owner)\n tokenContract.safeTransfer(msg.sender, amount);\n }\n\n /**\n * @notice Compute the total amount of LDY rewards that a given account is eligible to.\n * @dev Note: This function neither considers vesting nor already claimed rewards.\n * @param account The account to compute the eligible rewards of.\n * @return The total amount of LDY rewards that the account is eligible to.\n */\n function eligibleRewardsOf(address account) public view returns (uint256) {\n // Compute account's lock weight\n uint256 lockerWeight = accountsLocks[account].amount * accountsLocks[account].duration;\n\n // Compute amount of LDY that this locker is eligible to\n if (maxWeight == 0) return 0;\n else return (maxDistributedLDY * lockerWeight) / maxWeight;\n }\n\n /**\n * @notice Allows locking a specified amount of underlying tokens for a given duration.\n * By locking, an account became eligible to a portion of the distributed LDY rewards.\n * @dev This function proxies LToken.deposit()\n * @dev Lockers can extend their lock duration by calling this function again with a\n * greater duration and 0 as amount.\n * @param amount Amount of underlying tokens to lock.\n * @param duration Duration of the lock (in months).\n */\n function lock(uint256 amount, uint8 duration) external whenNotPaused {\n // Ensure Deposit phase has not ended yet\n require(!hasDepositPhaseEnded, \"L84\");\n\n // Ensure account hasn't already unlocked a past lock\n require(!accountsLocks[msg.sender].hasUnlocked, \"L71\");\n\n // Ensure lock duration is in valid range\n require(duration >= minLockDuration && duration <= maxLockDuration, \"L85\");\n\n // Ensure it won't exceed the hardcap\n require(totalLocked + amount <= uint256(lockedHardCap), \"L86\");\n\n // Increase account's locked amount\n accountsLocks[msg.sender].amount += uint240(amount);\n\n // Increase total locked amount accordingly\n totalLocked += amount;\n\n // Use existing lock duration if greater than the new one\n uint8 existingDuration = accountsLocks[msg.sender].duration;\n uint8 appliedDuration = existingDuration > duration ? existingDuration : duration;\n\n // Update account's lock duration\n accountsLocks[msg.sender].duration = appliedDuration;\n\n // Update account's lock end timestamp\n accountsLocks[msg.sender].lockEndTimestamp = uint40(\n block.timestamp + uint40(appliedDuration) * 30 days\n );\n\n // Emit a Lock event\n emit Lock(msg.sender, amount, appliedDuration);\n\n // If amount is 0, skip deposit\n if (amount == 0) return;\n\n // Transfer underlyingToken from account to contract\n underlyingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n // Deposit USDC in the L-Token contract\n underlyingToken.safeApprove(address(lToken), amount);\n lToken.deposit(amount);\n }\n\n /**\n * @notice Allows the caller to instaneously unlock its locked amount of underlying\n * tokens.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestUnlock() function otherwise.\n */\n function instantUnlock() external whenNotPaused safeUnlock {\n // Retrieve underlying tokens from the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.instantWithdrawal(unlockedAmount);\n\n // Transfer underlying tokens back to caller\n underlyingToken.safeTransfer(msg.sender, unlockedAmount);\n }\n\n /**\n * @notice Allows the call to request for the unlocking of its locked amount of\n * underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n */\n function requestUnlock() external payable whenNotPaused safeUnlock {\n // Put account in the unlock requests queue\n unlockRequests.push(msg.sender);\n\n // Request underlying tokens to the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.requestWithdrawal{value: msg.value}(unlockedAmount);\n }\n\n /**\n * @notice Processes queued unlock requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n */\n function processUnlockRequests() external onlyOwner {\n // Store the current request ID to process\n uint256 processedId = unlockRequestsCursor;\n\n // Loop over remaining requests\n while (processedId < unlockRequests.length) {\n // Prevent OOG by stopping request processing if there is not enough gas left\n // to continue the loop and properly end the function call.\n if (gasleft() < 45000) break;\n\n // Retrieve the request account\n address unlockAccount = unlockRequests[processedId];\n\n // Retrieve the unlocked amount\n uint256 unlockAmount = accountsLocks[unlockAccount].amount;\n\n // If the request has already been processed, skip it\n if (unlockAccount != address(0)) {\n // If the contract doesn't hold enough underlying tokens to process the request, stop here\n if (underlyingToken.balanceOf(address(this)) < unlockAmount) break;\n\n // Delete the request\n delete unlockRequests[processedId];\n\n // Transfer underlying back to account\n underlyingToken.safeTransfer(unlockAccount, unlockAmount);\n }\n\n // Increment processed request ID\n processedId++;\n }\n\n // Write back the cursor in storage\n unlockRequestsCursor = processedId;\n }\n\n /**\n * @notice Computes the amount of LDY rewards available to claim for a given account.\n * @dev This function considers vesting and already claimed rewards.\n * @param account The account to compute the available rewards of.\n * @return The amount of LDY rewards available to claim.\n */\n function availableToClaim(address account) public view returns (uint256) {\n // Compute total amount of rewards allocated to this locker\n uint256 totalEligibleRewards = eligibleRewardsOf(account);\n\n // Compute vesting duration in seconds\n uint256 vestingInSeconds = uint256(vestingDuration) * 30 days;\n\n // Compute elapsed months since claim phase started, and cap it to vesting duration\n uint256 elapsedTime = block.timestamp - claimPhaseStartTimestamp;\n if (elapsedTime > vestingInSeconds) elapsedTime = vestingInSeconds;\n\n // Compute total available to claim (proportionally to elapsed time)\n uint256 totalAvailableToClaim = (totalEligibleRewards * elapsedTime) / vestingInSeconds;\n\n // Else return net claimable (available minus already claimed)\n return totalAvailableToClaim - accountsLocks[account].claimedRewards;\n }\n\n /// @notice Allows the caller to claim its available LDY rewards.\n function claimRewards() external whenNotPaused {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L87\");\n\n // Compute claimable LDY rewards\n uint256 claimableLDY = availableToClaim(msg.sender);\n\n // Increase account claimed amount accordingly\n accountsLocks[msg.sender].claimedRewards += uint216(claimableLDY);\n\n // Transfer rewards to account\n ldyToken.safeTransfer(msg.sender, claimableLDY);\n }\n}\n" - } - }, - "settings": { - "evmVersion": "london", - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": ["ast"] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} diff --git a/contracts/hardhat/deployments/localhost/solcInputs/a268142553104e6d2a73dbd3773cf551.json b/contracts/hardhat/deployments/localhost/solcInputs/a268142553104e6d2a73dbd3773cf551.json new file mode 100644 index 00000000..e624963b --- /dev/null +++ b/contracts/hardhat/deployments/localhost/solcInputs/a268142553104e6d2a73dbd3773cf551.json @@ -0,0 +1,162 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeTo(address newImplementation) public virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n *\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../security/PausableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC20 token with pausable token transfers, minting and burning.\n *\n * Useful for scenarios such as preventing trades until the end of an evaluation\n * period, or having an emergency switch for freezing all token transfers in the\n * event of a large bug.\n *\n * IMPORTANT: This contract does not include public pause and unpause functions. In\n * addition to inheriting this contract, you must define both functions, invoking the\n * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate\n * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will\n * make the contract unpausable.\n */\nabstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {\n function __ERC20Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __ERC20Pausable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {ERC20-_beforeTokenTransfer}.\n *\n * Requirements:\n *\n * - the contract must not be paused.\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n require(!paused(), \"ERC20Pausable: token transfer while paused\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Wrapper.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../utils/SafeERC20Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of the ERC20 token contract to support token wrapping.\n *\n * Users can deposit and withdraw \"underlying tokens\" and receive a matching number of \"wrapped tokens\". This is useful\n * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the\n * wrapping of an existing \"basic\" ERC20 into a governance token.\n *\n * _Available since v4.2._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable {\n IERC20Upgradeable private _underlying;\n\n function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n __ERC20Wrapper_init_unchained(underlyingToken);\n }\n\n function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing {\n require(underlyingToken != this, \"ERC20Wrapper: cannot self wrap\");\n _underlying = underlyingToken;\n }\n\n /**\n * @dev See {ERC20-decimals}.\n */\n function decimals() public view virtual override returns (uint8) {\n try IERC20MetadataUpgradeable(address(_underlying)).decimals() returns (uint8 value) {\n return value;\n } catch {\n return super.decimals();\n }\n }\n\n /**\n * @dev Returns the address of the underlying ERC-20 token that is being wrapped.\n */\n function underlying() public view returns (IERC20Upgradeable) {\n return _underlying;\n }\n\n /**\n * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.\n */\n function depositFor(address account, uint256 amount) public virtual returns (bool) {\n address sender = _msgSender();\n require(sender != address(this), \"ERC20Wrapper: wrapper can't deposit\");\n SafeERC20Upgradeable.safeTransferFrom(_underlying, sender, address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(_underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = _underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20Upgradeable {\n using AddressUpgradeable for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20PermitUpgradeable token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable2Step.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to\n * 0 before setting it to a non-zero value.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/src/abstracts/base/BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"../GlobalOwnableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"../GlobalRestrictableUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../RecoverableUpgradeable.sol\";\n\n/**\n * @title BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract acts as a base for numerous contracts in this codebase,\n * minimizing code repetition and enhancing readability and maintainability.\n *\n * @dev For further details, see \"Base\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract BaseUpgradeable is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n GlobalPausableUpgradeable,\n GlobalRestrictableUpgradeable,\n RecoverableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_\n ) internal onlyInitializing {\n __UUPSUpgradeable_init();\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n __Recoverable_init_unchained();\n }\n\n function __Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/base/ERC20BaseUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport {ERC20PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"./BaseUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"../GlobalPausableUpgradeable.sol\";\n\n/**\n * @title ERC20BaseUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This abstract contract is an extension of BaseUpgradeable intended to be used\n * as a base for ERC20 tokens contracts.\n *\n * @dev For further details, see \"ERC20BaseUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract ERC20BaseUpgradeable is\n ERC20Upgradeable,\n BaseUpgradeable,\n ERC20PausableUpgradeable\n{\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param name_ The display name of the token.\n * @param symbol_ The symbol of the token.\n */\n function __ERC20Base_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n string memory name_,\n string memory symbol_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __ERC20_init(name_, symbol_);\n __ERC20Pausable_init_unchained();\n }\n\n function __ERC20Base_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and PausableUpgradeable parent contracts.\n * The GlobalPausableUpgradeable version is preferred because it checks the pause\n * state from the GlobalPause contract.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, PausableUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @dev Required override of _beforeTokenTransfer() which is implemented by both\n * ERC20PausableUpgradeable and ERC20Upgradeable parent contracts.\n * The ERC20PausableUpgradeable version is preferred because it also checks that\n * the contract is not paused before allowing the transfer.\n * @inheritdoc ERC20PausableUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n )\n internal\n virtual\n override(ERC20PausableUpgradeable, ERC20Upgradeable)\n whenNotPaused\n notBlacklisted(from)\n notBlacklisted(to)\n {\n ERC20PausableUpgradeable._beforeTokenTransfer(from, to, amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalOwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {GlobalOwner} from \"../GlobalOwner.sol\";\n\n/**\n * @title GlobalOwnableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit ownership from the specified GlobalOwner\n * contract (see GlobalOwner.sol). This design facilitates centralized management\n * of ownership for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalOwner state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalOwnableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalOwnableUpgradeable is Initializable, OwnableUpgradeable {\n /**\n * @notice The GlobalOwner contract the ownership will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalOwner private _globalOwner;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __GlobalOwnable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init_unchained(globalOwner_);\n // Note: __Ownable_init() doesn't have to be called as the overriden owner()\n // function no longer rely on the _owner state. Since __Ownable_init() only sets\n // the initial _owner value, calling it would have no effect.\n }\n\n function __GlobalOwnable_init_unchained(address globalOwner_) internal onlyInitializing {\n _globalOwner = GlobalOwner(globalOwner_);\n }\n\n /**\n * @notice Retrieves the address of GlobalOwner contract.\n * @return The address of the GlobalOwner contract.\n */\n function globalOwner() public view returns (address) {\n return address(_globalOwner);\n }\n\n /**\n * @notice Override of OwnableUpgradeable.owner() that retrieves the owner's address\n * from the GlobalOwner contract instead.\n * @return The address of the owner\n */\n function owner() public view override returns (address) {\n return _globalOwner.owner();\n }\n\n /**\n * @notice Override of OwnableUpgradeable.transferOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function transferOwnership(address newOwner) public view override onlyOwner {\n newOwner; // Silence unused variable compiler warning\n revert(\"L8\");\n }\n\n /**\n * @notice Override of OwnableUpgradeable.renounceOwnership() that always reverts.\n * Ownership is managed by the GlobalOwner contract and must be modified there.\n */\n function renounceOwnership() public view override onlyOwner {\n revert(\"L65\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalPausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalPause} from \"../GlobalPause.sol\";\n\n/**\n * @title GlobalPausableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a pause state from the specified GlobalPause\n * contract (see GlobalPause.sol). This design facilitates centralized management of\n * pause state for all the Ledgity Yield contracts.\n *\n * @dev Security measure\n * The _globalPause state must be set at initialization time and, for evident security\n * reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalPausableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalPausableUpgradeable is Initializable, PausableUpgradeable {\n /**\n * @notice The GlobalPause contract the pause state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalPause private _globalPause;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalPause_ The address of the GlobalPause contract.\n */\n function __GlobalPausable_init(address globalPause_) internal onlyInitializing {\n __Pausable_init();\n __GlobalPausable_init_unchained(globalPause_);\n }\n\n function __GlobalPausable_init_unchained(address globalPause_) internal onlyInitializing {\n _globalPause = GlobalPause(globalPause_);\n }\n\n /**\n * @notice Retrieves the address of GlobalPause contract.\n * @return The address of the GlobalPause contract.\n */\n function globalPause() public view returns (address) {\n return address(_globalPause);\n }\n\n /**\n * @notice Override of PausableUpgradeable.pause() that retrieves the pause state\n * from the GlobalPause contract instead.\n * @return Whether the contract is paused or not.\n */\n function paused() public view virtual override returns (bool) {\n return _globalPause.paused();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/GlobalRestrictableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalBlacklist} from \"../GlobalBlacklist.sol\";\n\n/**\n * @title GlobalRestrictableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts will inherit a blacklist state from the specified\n * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates\n * centralized management of a blacklist for all the Ledgity Yield contracts.\n *\n * @dev Security measure:\n * The _globalBlacklist state must be set at initialization time and, for evident\n * security reasons, cannot be changed afterward.\n *\n * @dev For further details, see \"GlobalRestrictableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract GlobalRestrictableUpgradeable is Initializable {\n /**\n * @notice The GlobalBlacklist contract the blacklist state will be inherited from.\n * @dev This state is private so derived contracts cannot change its value.\n */\n GlobalBlacklist private _globalBlacklist;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n */\n function __GlobalRestrictable_init(address globalBlacklist_) internal onlyInitializing {\n __GlobalRestrictable_init_unchained(globalBlacklist_);\n }\n\n function __GlobalRestrictable_init_unchained(\n address globalBlacklist_\n ) internal onlyInitializing {\n _globalBlacklist = GlobalBlacklist(globalBlacklist_);\n }\n\n /**\n * @notice Retrieves the address of GlobalBlacklist contract.\n * @return The address of the GlobalBlacklist contract.\n */\n function globalBlacklist() public view returns (address) {\n return address(_globalBlacklist);\n }\n\n /**\n * @notice Reverts if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n */\n modifier notBlacklisted(address account) {\n require(isBlacklisted(account) == false, \"L9\");\n _;\n }\n\n /**\n * @notice Checks if the given account is blacklisted by the GlobalBlacklist contract.\n * @param account Address to verify.\n * @return Whether the account is blacklisted.\n */\n function isBlacklisted(address account) internal view returns (bool) {\n return _globalBlacklist.isBlacklisted(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/InvestUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Contracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\nimport {GlobalPausableUpgradeable} from \"./GlobalPausableUpgradeable.sol\";\nimport {GlobalRestrictableUpgradeable} from \"./GlobalRestrictableUpgradeable.sol\";\nimport \"./base/BaseUpgradeable.sol\";\nimport {RecoverableUpgradeable} from \"../abstracts/RecoverableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {APRHistory as APRH} from \"../libs/APRHistory.sol\";\nimport {SUD} from \"../libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title InvestUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with utilities to manage an invested token,\n * users' investment periods, rewards calculations, virtual balances, and auto-compounding.\n *\n * @dev Intuition:\n * This contract primarily exists for code splitting and reusability. It unburdens the\n * LToken contract code, making it easier to understand and maintain.\n *\n * This contract is generic because it may be used in the LDYStaking contract in the future.\n *\n * @dev Definitions:\n * - Investment: The act of depositing or investing tokens into the contract.\n * - Investment period: Time between the last invested amount change and the present.\n * - Virtual balance: Temporary storage for account rewards, used when those can't be\n * distributed between investment periods.\n * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another.\n *\n * @dev Derived contract must:\n * - Set invested token during initialization\n * - Implement _investmentOf() function\n * - (optionally) Implement _distributeRewards() function\n *\n * @dev For further details, see \"InvestmentUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract InvestUpgradeable is BaseUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using APRH for APRH.Pack[];\n\n /**\n * @notice Represents an account's investment period.\n * @param timestamp The timestamp of the most recent rewards distribution.\n * @param ref The reference of the last APR checkpoint at that timestamp.\n */\n struct InvestmentPeriod {\n uint40 timestamp; // Supports dates up to 20/02/36812\n APRH.Reference ref;\n }\n\n /**\n * @notice Represents the investment details of an account.\n * @param period The current investment period of the account.\n * @param virtualBalance May hold a part of account rewards until they are claimed.\n */\n struct AccountDetails {\n InvestmentPeriod period;\n uint256 virtualBalance;\n }\n\n /// @notice Holds a reference to the invested token's contract.\n IERC20Upgradeable private _invested;\n\n /// @notice Holds investment details of each account.\n mapping(address => AccountDetails) internal accountsDetails;\n\n /// @notice Holds an history of the APR value over time (see APRHistory.sol).\n APRH.Pack[] private _aprHistory;\n\n /// @notice Holds active rewards redirections in both from->to and to->from[] ways.\n mapping(address => address) public rewardsRedirectsFromTo;\n mapping(address => address[]) public rewardsRedirectsToFrom;\n\n /// @notice Is used to prevent infinite loop in _beforeInvestmentChange().\n bool private _isClaiming;\n\n /**\n * @notice Emitted to inform listeners about a change in the APR's value.\n * @param newAPRUD7x3 The new APR in UD7x3 format.\n */\n event APRChangeEvent(uint16 newAPRUD7x3);\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param invested_ The address of the invested token contract.\n */\n function __Invest_init(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address invested_\n ) internal onlyInitializing {\n __Base_init(globalOwner_, globalPause_, globalBlacklist_);\n __Invest_init_unchained(invested_);\n }\n\n function __Invest_init_unchained(address invested_) internal onlyInitializing {\n // Set invested token\n _invested = IERC20Upgradeable(invested_);\n\n // Define initial APR to 0%. This would prevent getAPR() from reverting because\n // of an empty APR history\n _aprHistory.setAPR(0);\n }\n\n /**\n * @notice Retrieves the reference to the invested token contract.\n * @return The reference to the invested token contract.\n */\n function invested() public view returns (IERC20Upgradeable) {\n return _invested;\n }\n\n /**\n * @notice Updates the investment APR. Restricted to owner.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(uint16 aprUD7x3) public onlyOwner {\n _aprHistory.setAPR(aprUD7x3);\n emit APRChangeEvent(aprUD7x3);\n }\n\n /**\n * @notice Retrieves the most recently set APR.\n * @return The current APR in UD7x3 format.\n */\n function getAPR() public view returns (uint16) {\n return _aprHistory.getAPR();\n }\n\n /**\n * @notice Enables redirection of rewards from one account to another.\n * @param from The address of the account to redirect rewards from.\n * @param to The address of the account to redirect rewards to.\n */\n function startRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure the address is not already redirecting rewards\n require(rewardsRedirectsFromTo[from] == address(0), \"L62\");\n\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L12\");\n require(to != address(0), \"L13\");\n\n // Ensure 'from' and 'to' addresses are distinct\n require(from != to, \"L14\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L15\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Activate rewards redirection\n rewardsRedirectsFromTo[from] = to;\n rewardsRedirectsToFrom[to].push(from);\n }\n\n /**\n * @notice Disable an active rewards redirection.\n * @param from The address of the account to stop redirecting rewards from.\n * @param to The address of the account to stop redirecting rewards to.\n */\n function stopRewardsRedirection(\n address from,\n address to\n ) public whenNotPaused notBlacklisted(from) notBlacklisted(to) {\n // Ensure neither 'from' nor 'to' are the zero address\n require(from != address(0), \"L16\");\n require(to != address(0), \"L17\");\n\n // Ensure function caller is either the owner or the 'from' address\n require(_msgSender() == owner() || _msgSender() == from, \"L18\");\n\n // Ensure a rewards redirection was active\n require(rewardsRedirectsFromTo[from] == to, \"L19\");\n\n // Distribute current rewards and reset investment periods of both accounts\n _beforeInvestmentChange(from, true);\n _beforeInvestmentChange(to, true);\n\n // Retrieve 'from' index in the redirection array of 'to'\n int256 fromIndex = -1;\n for (uint256 i = 0; i < rewardsRedirectsToFrom[to].length; i++) {\n if (rewardsRedirectsToFrom[to][i] == from) {\n fromIndex = int256(i);\n break;\n }\n }\n\n // fromIndex should never be -1 at this point\n assert(fromIndex >= 0);\n\n // Deactivate rewards redirection\n rewardsRedirectsFromTo[from] = address(0);\n rewardsRedirectsToFrom[to][uint256(fromIndex)] = rewardsRedirectsToFrom[to][\n rewardsRedirectsToFrom[to].length - 1\n ];\n rewardsRedirectsToFrom[to].pop();\n }\n\n /**\n * @notice Retrieves the total amount of tokens invested by the given account.\n * @dev Derived contracts must implement this function.\n * @param account The account to get the investment of.\n * @return The total amount of tokens invested by the given account.\n */\n function _investmentOf(address account) internal view virtual returns (uint256);\n\n /**\n * @notice Distributes a specified amount of rewards to a given account.\n * @dev Derived contracts may optionally implement this function.\n * @dev Implementations must return true to indicate a successful distribution, and\n * false otherwise. If it returns false, the rewards will be added to the account's\n * virtual balance, in order to be claimed later.\n * @param account The account to claim the rewards of.\n * @param amount The amount of rewards to claim.\n * @return Whether the rewards distribution was successfull.\n */\n function _distributeRewards(address account, uint256 amount) internal virtual returns (bool) {\n account; // Silence unused variables warning\n amount;\n return false;\n }\n\n /**\n * @notice Computes the rewards accrued over a specified period of time, based on a\n * given APR and amount of invested tokens.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param beginTimestamp The moment the period commenced.\n * @param endTimestamp The moment the period concluded.\n * @param aprUD7x3 The APR during this period, in UD7x3 format.\n * @param investedAmount The amount of tokens deposited/invested during the period.\n * @return The amount of rewards generated during the period.\n */\n function _calculatePeriodRewards(\n uint40 beginTimestamp,\n uint40 endTimestamp,\n uint16 aprUD7x3,\n uint256 investedAmount\n ) internal view returns (uint256) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Compute the number of elapsed years\n uint256 elapsedTimeSUD = SUD.fromInt(endTimestamp - beginTimestamp, d);\n uint256 elapsedYearsSUD = (elapsedTimeSUD * SUD.fromInt(1, d)) / SUD.fromInt(365 days, d);\n\n // Compute the growth in invested amount (thanks to rewards)\n uint256 aprSUD = SUD.fromRate(aprUD7x3, d);\n uint256 growthSUD = (elapsedYearsSUD * aprSUD) / SUD.fromInt(1, d);\n\n // Compute and return the rewards\n uint256 investedAmountSUD = SUD.fromAmount(investedAmount, d);\n uint256 rewardsSUD = (investedAmountSUD * growthSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(rewardsSUD, d);\n }\n\n /**\n * @notice Computes the sum of given account's invested amount, plus invested amount\n * of all accounts that recursively redirect rewards to this account.\n * @param account The account to calculate the deep investment of.\n * @return deepInvestedAmount The deep invested amount.\n */\n function _deepInvestmentOf(address account) internal view returns (uint256 deepInvestedAmount) {\n // Consider account's direct investment\n deepInvestedAmount += _investmentOf(account);\n\n // But also the deep investments of all accounts redirecting rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n deepInvestedAmount += _deepInvestmentOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Computes the amount of unclaimed/undistributed rewards of a given account.\n * @dev For further details, see \"InvestUpgradeable > Rewards calculation\" section of\n * the whitepaper.\n * @param account The account to calculate the unclaimed rewards of.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n * @return rewards The amount of unclaimed/undistributed rewards of the given account.\n */\n function _rewardsOf(\n address account,\n bool autocompound\n ) internal view returns (uint256 rewards) {\n // Retrieve account's investment details\n AccountDetails memory details = accountsDetails[account];\n\n // Retrieve account's deep invested amount\n uint256 investedAmount = _deepInvestmentOf(account);\n\n // Return 0 if the account has never invested or has no invested amount\n if (details.period.timestamp == 0 || investedAmount == 0) return 0;\n\n // Retrieve reference and data of APR checkpoint at which started investment period\n APRH.Reference memory currRef = details.period.ref;\n APRH.CheckpointData memory currCheckpoint = _aprHistory.getDataFromReference(currRef);\n\n // Retrieve reference of latest APR checkpoint\n APRH.Reference memory latestRef = _aprHistory.getLatestReference();\n\n // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet)\n // See \"InvestUpgradeable > Yield calculation > 1)\" section of the whitepaper\n rewards = details.virtualBalance;\n\n // If start checkpoint is not the latest one\n if (!APRH.eq(currRef, latestRef)) {\n // Retrieve reference and data of APR checkpoint that comes after start checkpoint\n APRH.Reference memory nextRef = APRH.incrementReference(currRef);\n APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // 2) Calculate rewards from investment period start to next checkpoint\n // See \"InvestUpgradeable > Yield calculation > 2)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n\n // 3) Calculate rewards for each crossed pair of checkpoints\n // See \"InvestUpgradeable > Yield calculation > 3)\" section of the whitepaper\n while (true) {\n // Set next checkpoint as the current one\n currRef = nextRef;\n currCheckpoint = nextCheckpoint;\n\n // Break if current checkpoint is the latest one\n if (APRH.eq(currRef, latestRef)) break;\n\n // Else, retrieve the new next checkpoint\n nextRef = APRH.incrementReference(currRef);\n nextCheckpoint = _aprHistory.getDataFromReference(nextRef);\n\n // Calculate rewards between the current pair of checkpoints\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n nextCheckpoint.timestamp,\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n\n // 4) Calculate rewards from the latest checkpoint to now\n // See \"InvestUpgradeable > Yield calculation > 4)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n currCheckpoint.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n } else {\n // 2.bis) Calculate rewards from investment period start to now\n // See \"InvestUpgradeable > Yield calculation > 2.bis)\" section of the whitepaper\n rewards += _calculatePeriodRewards(\n details.period.timestamp,\n uint40(block.timestamp),\n currCheckpoint.aprUD7x3,\n investedAmount + (autocompound ? rewards : 0)\n );\n }\n }\n\n /**\n * @notice Recursively resets the investment period of the specified account and of\n * all accounts that directly or indirectly redirect rewards to this account.\n * @param account The account to deeply reset the investment period of.\n */\n function _deepResetInvestmentPeriodOf(address account) internal {\n // Reset account investment period timestamp and APR checkpoint to latest ones\n accountsDetails[account].period.timestamp = uint40(block.timestamp);\n accountsDetails[account].period.ref = _aprHistory.getLatestReference();\n\n // Also reset the ones of all accounts that recursively redirect rewards to this account\n for (uint256 i = 0; i < rewardsRedirectsToFrom[account].length; i++) {\n _deepResetInvestmentPeriodOf(rewardsRedirectsToFrom[account][i]);\n }\n }\n\n /**\n * @notice Hook to be invoked before the invested amount of an account changes. It\n * ensures that rewards are distributed and that account's investment period is reset.\n * @param account The account whose invested amount is going to change.\n * @param autocompound Whether to autocompound the rewards between APR checkpoints.\n */\n function _beforeInvestmentChange(address account, bool autocompound) internal {\n // This hook is called inside LToken._beforeTokenTransfer() and as new tokens are\n // minted in LToken._distributeRewards(), this guards against infinite loop.\n if (_isClaiming) return;\n\n // LToken._beforeTokenTransfer() calls this hook for both involved addresses.\n // As first call will treat both addresses, the second call would be redundant.\n // Therefore, we skip accounts already processed in this block to save up some gas.\n if (accountsDetails[account].period.timestamp == uint40(block.timestamp)) return;\n\n // If account redirects its rewards\n address redirectRewardsTo = rewardsRedirectsFromTo[account];\n if (redirectRewardsTo != address(0)) {\n // Call hook on redirection target (this will indirectly reset the investment\n // of this source account) and return\n _beforeInvestmentChange(redirectRewardsTo, autocompound);\n return;\n }\n\n // Else, compute account's undistributed/unclaimed rewards\n uint256 rewards = _rewardsOf(account, autocompound);\n\n // If there are some rewards\n if (rewards > 0) {\n // Try to distribute rewards to account\n _isClaiming = true;\n bool distributed = _distributeRewards(account, rewards);\n _isClaiming = false;\n\n // If rewards have not been distributed, accumulate them in account's virtual balance\n if (!distributed) accountsDetails[account].virtualBalance = rewards;\n }\n\n // Finally, deeply reset investment period of the account\n _deepResetInvestmentPeriodOf(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/abstracts/RecoverableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Conracts\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./GlobalOwnableUpgradeable.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title RecoverableUpgradeable\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Derived contracts are provided with helper functions allowing the recovery of\n * assets accidentally sent to them.\n *\n * @dev Where are utilities Ether, ERC721, etc.?\n * This abstract contract currently supports only ERC20 tokens. Derived contracts\n * in this codebase currently do not implement the necessary functions to receive Ether\n * or ERC721/ERC1155 tokens, so no recovery functions are provided for these assets.\n *\n * @dev For further details, see \"RecoverableUpgradeable\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nabstract contract RecoverableUpgradeable is Initializable, GlobalOwnableUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /**\n * @notice Initializer functions of the contract. They replace the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function __Recoverable_init(address globalOwner_) internal onlyInitializing {\n __GlobalOwnable_init(globalOwner_);\n __Recoverable_init_unchained();\n }\n\n function __Recoverable_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Recovers a specified amount of a given token address. Will fail if the\n * contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) public virtual onlyOwner {\n // Ensure the specified amount is not zero\n require(amount > 0, \"L10\");\n\n // Create a reference to token's contract\n IERC20Upgradeable tokenContract = IERC20Upgradeable(tokenAddress);\n\n // Ensure there is enough token to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L11\");\n\n // Transfer the recovered token amount to the sender\n tokenContract.safeTransfer(_msgSender(), amount);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add\n * new variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "contracts/src/DummyLDYStaking.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title LDYStaking\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This contract acts as a placeholder for the real LDYStaking contract until\n * this one is deployed.\n *\n * @dev This contract only implements tierOf() function from LDYStaking as it's the only\n * one the LToken contract relies on.\n *\n * @custom:security-contact security@ledgity.com\n */\ncontract LDYStaking is Ownable2Step {\n /**\n * @notice Holds a mapping of addresses that default to the highest staking tier.\n * @dev This is notably used to allow PreMining contracts to benefit from 0%\n * withdrawal fees in L-Tokens contracts, when accounts unlock their funds.\n */\n mapping(address => bool) public highTierAccounts;\n\n /**\n * @notice Update high tier status of a given account.\n * @param account The account to update the high tier status of.\n */\n function setHighTierAccount(address account, bool status) public onlyOwner {\n highTierAccounts[account] = status;\n }\n\n /**\n * @dev Dummy tierOf() function that always return that the given account is not\n * elligible to any LDY staking tier, except if the account is in the\n * highTierAccounts mapping.\n * @param account The account to check the tier of.\n */\n function tierOf(address account) public view returns (uint256 tier) {\n if (highTierAccounts[account]) return 3;\n return 0;\n }\n}\n" + }, + "contracts/src/GlobalBlacklist.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalBlacklist\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global mapping of blacklisted accounts shared by all contracts of the\n * Ledgity Yield codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers\n * and getter functions to easily check against this global blacklist.\n *\n * @dev For further details, see \"GlobalBlacklist\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalBlacklist is Initializable, UUPSUpgradeable, GlobalOwnableUpgradeable {\n /**\n * @notice Mapping of accounts to their blacklist status.\n * @dev This mapping is made private and isBlacklisted() should be used instead.This\n * helps saving gas in some scenario. See isBlacklisted() documentation for more details.\n */\n mapping(address => bool) private _list;\n\n /// @dev Emitted when `account` is blacklisted.\n event Blacklisted(address account);\n\n /// @dev Emitted when `account` is unblacklisted.\n event Unblacklisted(address account);\n\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @notice Adds a given account to the blacklist.\n * @param account The account's address to be blacklisted.\n */\n function blacklist(address account) external onlyOwner {\n require(account != address(0), \"L20\");\n _list[account] = true;\n emit Blacklisted(account);\n }\n\n /**\n * @notice Removes a given account from the blacklist.\n * @param account The account's address to be un-blacklisted.\n */\n function unBlacklist(address account) external onlyOwner {\n _list[account] = false;\n emit Unblacklisted(account);\n }\n\n /**\n * @notice Checks whether a given account is blacklisted.\n * @param account Address of the account to check.\n * @return 'true' if the account is blacklisted, 'false' otherwise\n */\n function isBlacklisted(address account) external view returns (bool) {\n // Gas optimization: Avoid accessing storage if account is the zero address\n // (e.g, during a mint or a burn of tokens)\n if (account == address(0)) return false;\n\n // Else, return current account's blacklist status\n return _list[account];\n }\n}\n" + }, + "contracts/src/GlobalOwner.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\n/**\n * @title GlobalOwner\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds the address of a global owner account shared by all contracts of the\n * Ledgity Yield's codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalOwnableUpgradeable abstract contract. This provides them with an overriden\n * owner() function that retrieves the owner's address from this contract instead.\n *\n * @dev For further details, see \"GlobalOwner\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalOwner is Initializable, UUPSUpgradeable, Ownable2StepUpgradeable {\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n */\n function initialize() public initializer {\n __Ownable2Step_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n}\n" + }, + "contracts/src/GlobalPause.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {UUPSUpgradeable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {GlobalOwnableUpgradeable} from \"./abstracts/GlobalOwnableUpgradeable.sol\";\n\n/**\n * @title GlobalPause\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Holds a global pause state shared by all contracts of the Ledgity Yield\n * codebase.\n *\n * @dev Specifically, some contracts within the codebase inherit from the\n * GlobalPausableUpgradeable abstract contract. This provides them with an overriden\n * paused() function that retrieves the pause state from this contract instead.\n *\n * @dev For further details, see \"GlobalPause\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\ncontract GlobalPause is\n Initializable,\n UUPSUpgradeable,\n GlobalOwnableUpgradeable,\n PausableUpgradeable\n{\n /**\n * @notice Prevents implementation contract from being initialized as recommended by\n * OpenZeppelin.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-_disableInitializers--\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n */\n function initialize(address globalOwner_) public initializer {\n __GlobalOwnable_init(globalOwner_);\n __Pausable_init();\n __UUPSUpgradeable_init();\n }\n\n /**\n * @notice Override of UUPSUpgradeable._authorizeUpgrade() function restricted to\n * global owner. It is called by the proxy contract during an upgrade.\n * @param newImplementation The address of the new implementation contract.\n */\n function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}\n\n /**\n * @dev Public implementation of PausableUpgradeable's pausing and unpausing functions\n * but restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n}\n" + }, + "contracts/src/interfaces/ITransfersListener.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ITransfersListener {\n function onLTokenTransfer(address from, address to, uint256 amount) external;\n}\n" + }, + "contracts/src/libs/APRHistory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/**\n * @title APRHistory\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice This library offers utilities to efficiently maintain the history of an\n * on-chain APR (Annual Percentage Rate) state. Each entry in this history is called\n * a \"checkpoint\".\n *\n * @dev Intuition:\n * Each checkpoint in an APR history consists of two data:\n * - the creation timestamp\n * - the APR at that time\n *\n * Given that reading and writing to storage slots are among the most costly operations\n * in Solidity, this library provides a way to store those data in a way that minimizes\n * the number of used storage slots.\n *\n * Instead of storing each checkpoint in a separate storage slot, this library\n * facilitates the packing of up to 4 checkpoints in a single storage slot.\n *\n * @dev Definitions:\n * - Checkpoint: A record of an APR change\n * - Pack: A collection of 4 checkpoints stored in a single storage slot\n * - History: A dynamic array of packs\n * - Reference: A storage pointer to a checkpoint in the APR history\n * - CheckpointData: An in-memory representation of a checkpoint data\n *\n * @dev Value limitation:\n * This library can accommodate APRs only up to 65.536%. This is however sufficient for\n * APR in LToken contract, which is expected to remain below 10%.\n *\n * @dev For further details, see \"APRHistory\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary APRHistory {\n /**\n * @notice Represents data of a checkpoint extracted from the on-chain history.\n * For on-chain representation see \"Pack\" struct.\n * @param aprUD7x3 APR in UD7x3 format (e.g., 12345 = 12.345%).\n * @param timestamp Timestamp of the checkpoint's creation.\n */\n struct CheckpointData {\n uint16 aprUD7x3; // Allows up to 65.536%\n uint40 timestamp; // Supports dates up to 20/02/36812\n }\n\n /**\n * @notice Represents how APR checkpoints are stored on chain. Each pack can contain\n * the data 4 checkpoints. Packs are then stored in a dynamic array (the history).\n * @param aprsUD7x3 Array of checkpoints' APRs.\n * @param timestamps Array of checkpoints' timestamps.\n * @param cursor Index of the next checkpoint to be written.\n */\n struct Pack {\n uint16[4] aprsUD7x3;\n uint40[4] timestamps;\n uint32 cursor;\n }\n\n /**\n * @notice Represents a storage pointer to a specific checkpoint in the history.\n * @param packIndex Index of the pack the checkpoint belongs to.\n * @param cursorIndex Index of the checkpoint in this pack (between 0 and 3).\n */\n struct Reference {\n uint256 packIndex;\n uint32 cursorIndex;\n }\n\n /**\n * @notice Compares two checkpoints references.\n * @param ref1 The first reference to compare.\n * @param ref2 The second reference to compare.\n * @return Whether the two references points to the same checkpoint.\n */\n function eq(Reference memory ref1, Reference memory ref2) external pure returns (bool) {\n return ref1.packIndex == ref2.packIndex && ref1.cursorIndex == ref2.cursorIndex;\n }\n\n /**\n * @notice Returns the reference of the checkpoint that should come right after the\n * referenced checkpoint in the APR history.\n * @param ref The reference to be incremented.\n * @return The incremented reference.\n */\n function incrementReference(Reference memory ref) public pure returns (Reference memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L1\");\n\n // If the given ref is the last slot in its pack, return ref of next pack's first slot\n if (ref.cursorIndex == 3) return Reference(ref.packIndex + 1, 0);\n //\n // Else, return ref of next slot in current pack\n else return Reference(ref.packIndex, ref.cursorIndex + 1);\n }\n\n /**\n * @notice Extracts checkpoint data from a given reference and in APR history.\n * @param self The APR history to extract the checkpoint from.\n * @param ref The reference of the checkpoint data to extract.\n * @return The extracted checkpoint's data.\n */\n function getDataFromReference(\n Pack[] storage self,\n Reference memory ref\n ) public view returns (CheckpointData memory) {\n // Ensure cursor index of the given ref is within valid range [0, 3]\n require(ref.cursorIndex <= 3, \"L2\");\n\n // Ensure pack index of the given ref exists in history\n require(ref.packIndex < self.length, \"L3\");\n\n // Retrieve pack data from history\n Pack memory pack = self[ref.packIndex];\n\n // Ensure cursor index of the given ref has been written\n require(ref.cursorIndex < pack.cursor, \"L4\");\n\n // Build and return the checkpoint data\n return\n CheckpointData({\n aprUD7x3: pack.aprsUD7x3[ref.cursorIndex],\n timestamp: pack.timestamps[ref.cursorIndex]\n });\n }\n\n /**\n * @notice Retrieves the reference to the most recently added checkpoint in the APR history.\n * @param self The history to extract the reference from.\n * @return The reference of the latest checkpoint.\n */\n function getLatestReference(Pack[] storage self) public view returns (Reference memory) {\n // Ensure the given history is not empty\n require(self.length != 0, \"L5\");\n\n // Retrieve latest pack's index and cursor\n uint256 packIndex = self.length - 1;\n uint32 packCursor = self[packIndex].cursor;\n\n // If this is the first pack ever, ensure it is not empty\n if (packIndex == 0) require(packCursor != 0, \"L6\");\n\n // If the pack is empty, return ref of previous pack's latest slot\n if (packCursor == 0) return Reference(packIndex - 1, 3);\n //\n // Else, return ref of previous slot in current pack\n else return Reference(packIndex, packCursor - 1);\n }\n\n /**\n * @notice Appends a new empty pack to the end of the given APR history array.\n * @param self The APR history to append an empty to.\n */\n function newBlankPack(Pack[] storage self) internal {\n // If history is not empty, ensure the latest pack is full\n require(self.length == 0 || getLatestReference(self).cursorIndex == 3, \"L7\");\n\n // Push a new blank pack to the history array\n self.push(\n Pack({\n aprsUD7x3: [uint16(0), uint16(0), uint16(0), uint16(0)],\n timestamps: [uint40(0), uint40(0), uint40(0), uint40(0)],\n cursor: 0\n })\n );\n }\n\n /**\n * @notice Write a new APR checkpoint at the end of the given history array.\n * @param self The array of packs to write the new checkpoint to.\n * @param aprUD7x3 The new APR in UD7x3 format.\n */\n function setAPR(Pack[] storage self, uint16 aprUD7x3) external {\n // Determine the reference where the new checkpoint should be written\n Reference memory newRef = self.length == 0\n ? Reference(0, 0)\n : incrementReference(getLatestReference(self));\n\n // If pack to be written doesn't exist yet, push a new blank pack in history\n if (newRef.packIndex >= self.length) newBlankPack(self);\n\n // Retrieve the pack where the new checkpoint will be stored\n Pack memory pack = self[newRef.packIndex];\n\n // Add new checkpoint's data to the pack\n pack.aprsUD7x3[newRef.cursorIndex] = aprUD7x3;\n pack.timestamps[newRef.cursorIndex] = uint40(block.timestamp);\n\n // Increment the pack's cursor\n pack.cursor++;\n\n // Write the updated pack in storage\n self[newRef.packIndex] = pack;\n }\n\n /**\n * @notice Retrieves the APR of the latest checkpoint written in the APR history.\n * @param self The history array to read APR from.\n * @return The latest checkpoint's APR.\n */\n function getAPR(Pack[] storage self) public view returns (uint16) {\n // Retrieve the latest checkpoint data\n Reference memory ref = getLatestReference(self);\n CheckpointData memory data = getDataFromReference(self, ref);\n\n // Return the latest checkpoint's APR\n return data.aprUD7x3;\n }\n}\n" + }, + "contracts/src/libs/SUD.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @title SUD\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice SUD serves as an intermediary number format for calculations within this\n * codebase. It ensures consistency and reduces precision losses. This library\n * facilitates conversions between various number formats and the SUD format.\n *\n * @dev Intuition:\n * This codebase employs the UD (unsigned decimal fixed-point numbers) format to\n * represent both percentage rates and tokens amounts.\n *\n * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on\n * the decimals() value of the involved tokens.\n *\n * Three challenges arise from this:\n * 1) To compute values together, it's essential that they are in the same format\n * 2) Calculations involving consecutive divisions on UD numbers lead to accumulated\n * precision loss (because division shrinks). A common approach is to scale up and\n * down values by a few decimals before and after performing calculations.\n * 3) Given that rates use the UD7x3 format, if we decided to scale them to and from\n * the number of decimals of the involved token, 1 to 3 of the rates' decimals would\n * be shrunk in case token's decimals number is in [0, 2].\n *\n * To address these challenges, this library provides the SUD format, which acts as a\n * consistent and scaled intermediate format to perform calculations.\n *\n * SUD is an acronym for either \"Scaled UD\" or \"Safe UD\".\n *\n * @dev Definitions:\n * - Integer: A number without fractional part, e.g., block.timestamp\n * - UD: A decimal unsigned fixed-point number. The \"UD\" notation is inspired from\n * libraries like [prb-math](https://github.com/PaulRBerg/prb-math/)\n * - Amount: A token amount. A UD with an unknown repartition of digits between integral\n * and fractional parts (as token amounts have variable decimal numbers)\n * - Rate: A percentage rate. An UD with 7 integral digits and 3 fractional ones (= UD7x3)\n * - SUD: An intermediate format to perform calculations involving Rates and Amounts. A UD\n * with 3 more decimals than the involved UD with the highest decimals number. As\n * rates are represented by UD7x3, a SUD number has at least 6 decimals (3+3) and\n * so ranges from UD71x6 to UD0x77 formats.\n *\n * @dev A conversion library:\n * This library provides utilities to perform the following conversions:\n * - Amount <--> SUD\n * - Rate (UD7x3) <--> SUD\n * - Integer <--> SUD\n *\n * @dev Why scaling by 3 decimals?\n * - It provides an adequate degree of precision for this codebase,\n * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by\n * the involved token's decimal number, so is gas efficient.\n *\n * @dev Why internal functions?\n * The functions of this library are not set to external because incorporating them\n * directly into contracts is more gas-efficient. Given their minimal size and frequent\n * usage in the InvestUpgradeable, LDYStaking, and LToken contracts, any bytecode savings\n * from making them external are negated by the additional bytecode required for external\n * calls to this library. This can be observed by comparing the output of `bun cc:size`\n * when those functions's visibility is set to external or internal.\n *\n * @dev Precision warning:\n * While this library mitigates precision loss during calculations on UD numbers, it's\n * important to note that tokens with lower decimal counts and supply inherently suffer\n * more from precision loss. Conversely, tokens with higher decimal counts and supply\n * will experience less precision loss.\n *\n * @dev For further details, see \"SUD\" section of whitepaper.\n * @custom:security-contact security@ledgity.com\n */\nlibrary SUD {\n /**\n * @notice Retrieves decimals number of the given ERC20 contract address.\n * @param tokenAddress The address to retrieve decimals number from.\n * @return decimals The decimals number of the given ERC20 contract address.\n */\n function decimalsOf(address tokenAddress) internal view returns (uint256 decimals) {\n return IERC20MetadataUpgradeable(tokenAddress).decimals();\n }\n\n /**\n * @notice Convert a given token amount into SUD format.\n * @param nAmount The token amount to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The amount in SUD format\n */\n function fromAmount(uint256 nAmount, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nAmount * 10 ** (6 - decimals);\n\n // Else return a number with decimals+3 fractional digits\n return nAmount * 10 ** 3;\n }\n\n /**\n * @notice Convert a given SUD number into token amount format.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nAmount The number in amount format\n */\n function toAmount(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nAmount) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** (6 - decimals);\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** 3;\n }\n\n /**\n * @notice Converts a given UD7x3 rate into SUD format.\n * @param nUD7x3 The UD7x3 rate to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The rate in SUD format.\n */\n function fromRate(uint256 nUD7x3, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return nUD7x3 * 10 ** 3;\n\n // Else, return a number with decimals+3 fractional digits\n return nUD7x3 * 10 ** decimals;\n }\n\n /**\n * @notice Converts a given SUD number into a UD7x3 rate.\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nUD7x3 The number in UD7x3 rate format.\n */\n function toRate(uint256 nSUD, uint256 decimals) internal pure returns (uint256 nUD7x3) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 3;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** decimals;\n }\n\n /**\n * @notice Converts a given integer into SUD format.\n * @param n The integer to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return nSUD The integer in SUD format.\n */\n function fromInt(uint256 n, uint256 decimals) internal pure returns (uint256 nSUD) {\n // If token decimals < 3, return a UD71x6 number\n if (decimals < 3) return n * 10 ** 6;\n\n // Else, return a number with decimals+3 fractional digits\n return n * 10 ** (decimals + 3);\n }\n\n /**\n * @notice Converts a given SUD number as an integer (all decimals shrinked).\n * @param nSUD The SUD number to convert.\n * @param decimals The decimals number of the involved ERC20 token.\n * @return n The SUD number as an integer.\n */\n function toInt(uint256 nSUD, uint256 decimals) internal pure returns (uint256 n) {\n // If token decimals < 3, convert from a UD71x6 number\n if (decimals < 3) return nSUD / 10 ** 6;\n\n // Else, convert from a number with decimals+3 fractional digits\n return nSUD / 10 ** (decimals + 3);\n }\n}\n" + }, + "contracts/src/LToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// Contracts\nimport {ERC20WrapperUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol\";\nimport \"./abstracts/base/ERC20BaseUpgradeable.sol\";\nimport {InvestUpgradeable} from \"./abstracts/InvestUpgradeable.sol\";\nimport {LDYStaking} from \"./DummyLDYStaking.sol\";\n\n// Libraries\nimport {SafeERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\";\nimport {SUD} from \"./libs/SUD.sol\";\n\n// Interfaces\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport {IERC20MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport {ITransfersListener} from \"./interfaces/ITransfersListener.sol\";\n\n/**\n * @title LToken\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n *\n * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e.,\n * investment pools backed by RWA). An L-Token is an ERC20 wrapper around a stablecoin.\n * As soon as a wallet holds some L-Tokens, it starts receiving rewards in\n * the form of additional L-Tokens, which are auto-compounded over time.\n *\n * @dev Definitions:\n * - Deposit: Swap of underlying tokens for L-Tokens (1:1 ratio).\n * - Withdrawal: Swap of L-Tokens for underlying tokens (1:1 ratio, minus applicable fees).\n * - Instant: Processed immediately.\n * - Request: Queued for later processing.\n * - Big Request: A requested withdrawal exceeding half of the retention rate.\n * - (Withdrawal) queue: A list of all requested withdrawals sorted by priority.\n * - Request ID: The index of a withdrawal request in the queue array.\n * - Retention rate: Maximum fraction of underlying tokens TVL the contract can retain.\n * - Fees Rate: Percentage of fees applied to successful withdrawals.\n * - Usable underlyings: Amount of underlying tokens that have been deposited through\n * expected ways and are so considered safe to use by the contract.\n * - Transfers listeners: External contracts listening on L-Tokens transfers.\n * - Fund wallet: Wallet managed by the Ledgity's financial team.\n * - Withdrawer wallet: Managed by an off-chain server to automate withdrawal request\n * processing.\n *\n * Note that words between parenthesis are sometimes omitted for brevity.\n *\n * @dev Deployment notice:\n * This contract can safely receive funds immediately after initialization. (i.e., there\n * is no way for funds to be sent to non-owned addresses). It is, however, recommended to\n * replace ASAP owner and fund wallets with multi-sig wallets.\n *\n * @dev For further details, see \"LToken\" section of whitepaper.\n * @custom:oz-upgrades-unsafe-allow external-library-linking\n * @custom:security-contact security@ledgity.com\n */\ncontract LToken is ERC20BaseUpgradeable, InvestUpgradeable, ERC20WrapperUpgradeable {\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n /// @dev Represents type of actions triggering ActivityEvent events.\n enum Action {\n Deposit,\n Withdraw\n }\n\n /// @dev Represents different status of actions triggering ActivityEvent events.\n enum Status {\n Queued,\n Cancelled,\n Success,\n Moved\n }\n\n /**\n * @notice Represents a withdrawal request in the queue.\n * @dev A request fits in a single storage slot (32 bytes).\n * @param account The account that initiated the request.\n * @param amount The amount of underlying tokens requested.\n */\n struct WithdrawalRequest {\n address account; // 20 bytes\n uint96 amount; // 12 bytes\n }\n\n /// @notice Upper limit of retention rate.\n uint32 private constant MAX_RETENTION_RATE_UD7x3 = 10 * 10 ** 3; // 10%\n\n /// @notice Upper limit of fees rate.\n uint32 private constant MAX_FEES_RATE_UD7x3 = 20 * 10 ** 3; // 20%\n\n /// @notice Used in activity events to represent the absence of request ID.\n int256 private constant NO_ID = -1;\n\n /// @notice Holds a reference to the LDYStaking contract.\n LDYStaking public ldyStaking;\n\n /// @notice Holds address of withdrawer wallet (managed by withdrawal server).\n address payable public withdrawer;\n\n /// @notice Holds address of fund wallet (managed by Ledgity financial team).\n address public fund;\n\n /// @notice Holds the withdrawal fees rate in UD7x3 format (e.g., 350 = 0.350%).\n uint32 public feesRateUD7x3;\n\n /// @notice Holds the retention rate in UD7x3 format.\n uint32 public retentionRateUD7x3;\n\n /// @notice Holds the amount of withdrawal fees not yet claimed by contract's owner.\n uint256 public unclaimedFees;\n\n /// @notice Holds the amount of L-Tokens currently in the withdrawal queue.\n uint256 public totalQueued;\n\n /**\n * @notice Holds the amount of underlying tokens considered as usable by the contract.\n * @dev Are usable, only underlying tokens deposit through deposit() or fund() functions.\n */\n uint256 public usableUnderlyings;\n\n /// @notice Holds an ordered list of active withdrawal requests.\n WithdrawalRequest[] public withdrawalQueue;\n\n /// @notice Holds the index of the next withdrawal request to process in the queue.\n uint256 public withdrawalQueueCursor;\n\n /**\n * @notice Holds a list of all currently frozen withdrawal requests.\n * @dev If a request emitter as been blacklisted, its request is moved here to prevent\n * it from blocking the queue.\n */\n WithdrawalRequest[] public frozenRequests;\n\n /**\n * @notice Holds a list of contracts' references that are listening to L-Tokens transfers.\n * @dev onLTokenTransfer() functions of those contracts will be called on each transfer.\n */\n ITransfersListener[] public transfersListeners;\n\n /**\n * @notice Emitted to inform listeners about a change in the contract's TVL.\n * @dev TVL = realTotalSupply()\n * @param newTVL The new TVL of the contract.\n */\n event TVLChangeEvent(uint256 newTVL);\n\n /**\n * @notice Emitted to inform listerners about an activity related to deposits and withdrawals.\n * @param id ID of the involved withdrawal request or NO_ID (-1) if not applicable.\n * @param account The account involved in the activity.\n * @param action The type of activity.\n * @param amount The amount of underlying tokens involved in the activity.\n * @param newStatus The new status of the activity.\n * @param newId The new ID of the request if it has been moved in the queue.\n */\n event ActivityEvent(\n int256 indexed id,\n address indexed account,\n Action indexed action,\n uint256 amount,\n uint256 amountAfterFees,\n Status newStatus,\n int256 newId\n );\n\n /**\n * @notice Emitted to inform listeners that some rewards have been minted.\n * @param account The account that received the rewards.\n * @param balanceBefore The balance of the account before the minting.\n * @param rewards The amount of minted rewards.\n */\n event MintedRewardsEvent(address indexed account, uint256 balanceBefore, uint256 rewards);\n\n /// @notice Reverts if the function caller is not the withdrawer wallet.\n modifier onlyWithdrawer() {\n require(_msgSender() == withdrawer, \"L39\");\n _;\n }\n\n /// @notice Reverts if the function caller is not the fund wallet.\n modifier onlyFund() {\n require(_msgSender() == fund, \"L40\");\n _;\n }\n\n /**\n * @notice Initializer function of the contract. It replaces the constructor()\n * function in the context of upgradeable contracts.\n * @dev See: https://docs.openzeppelin.com/contracts/4.x/upgradeable\n * @param globalOwner_ The address of the GlobalOwner contract.\n * @param globalPause_ The address of the GlobalPause contract.\n * @param globalBlacklist_ The address of the GlobalBlacklist contract.\n * @param underlyingToken The address of the underlying stablecoin ERC20 token.\n */\n function initialize(\n address globalOwner_,\n address globalPause_,\n address globalBlacklist_,\n address ldyStaking_,\n address underlyingToken\n ) public initializer {\n // Initialize ERC20 base.\n string memory underlyingSymbol = IERC20MetadataUpgradeable(underlyingToken).symbol();\n __ERC20Base_init(\n globalOwner_,\n globalPause_,\n globalBlacklist_,\n string(abi.encodePacked(\"Ledgity \", underlyingSymbol)),\n string(abi.encodePacked(\"L\", underlyingSymbol))\n );\n\n // IMPORTANT: Below calls must not be restricted to owner at any point.\n // This is because the GlobalOwner contract may not be a fresh one, and so\n // the contract deployer may not be the owner anymore after ERC20Base init.\n\n // Initialize other parents contracts.\n __ERC20Wrapper_init(IERC20Upgradeable(underlyingToken));\n __Invest_init_unchained(address(this));\n\n // Set LDYStaking contract\n ldyStaking = LDYStaking(ldyStaking_);\n\n // Set initial withdrawal fees rate to 0.3%\n feesRateUD7x3 = 300;\n\n // Set initial retention rate to 10%\n retentionRateUD7x3 = 10_000;\n\n // Default withdrawer and fund wallet to contract owner address. This prevents\n // any loss of funds if a deposit/withdrawal is made before those are manually set.\n withdrawer = payable(owner());\n fund = payable(owner());\n }\n\n /**\n * @notice Required override of decimals() which is implemented by both\n * ERC20Upgradeable and ERC20WrapperUpgradeable parent contracts.\n * @dev The ERC20WrapperUpgradeable version is preferred because it mirrors the\n * decimals amount of the underlying stablecoin token.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function decimals()\n public\n view\n override(ERC20Upgradeable, ERC20WrapperUpgradeable)\n returns (uint8)\n {\n return ERC20WrapperUpgradeable.decimals();\n }\n\n /**\n * @notice Required override of paused() which is implemented by both\n * GlobalPausableUpgradeable and ERC20BaseUpgradeable parent contracts.\n * @dev Both version are the same as ERC20BaseUpgradeable.paused() mirrors\n * GlobalPausableUpgradeable.paused(), so a random one is chosen.\n * @inheritdoc GlobalPausableUpgradeable\n */\n function paused()\n public\n view\n virtual\n override(GlobalPausableUpgradeable, ERC20BaseUpgradeable)\n returns (bool)\n {\n return GlobalPausableUpgradeable.paused();\n }\n\n /**\n * @notice Updates the current withdrawal fee rate.\n * @param feesRateUD7x3_ The new withdrawal fee rate in UD7x3 format.\n */\n function setFeesRate(uint32 feesRateUD7x3_) public onlyOwner {\n require(feesRateUD7x3_ <= MAX_FEES_RATE_UD7x3, \"L88\");\n feesRateUD7x3 = feesRateUD7x3_;\n }\n\n /**\n * @notice Updates the current underlying token retention rate.\n * @dev The retention rate is capped at 10%, which ensures that no more than 10% of\n * deposited assets will ever be exposed in this contract (reduces attack surface).\n * @param retentionRateUD7x3_ The new retention rate in UD7x3 format.\n */\n function setRetentionRate(uint32 retentionRateUD7x3_) public onlyOwner {\n require(retentionRateUD7x3_ <= MAX_RETENTION_RATE_UD7x3, \"L41\");\n retentionRateUD7x3 = retentionRateUD7x3_;\n }\n\n /**\n * @notice Updates the address of LDYStaking contract.\n * @param ldyStakingAddress The address of the new LDYStaking contract.\n */\n function setLDYStaking(address ldyStakingAddress) public onlyOwner {\n ldyStaking = LDYStaking(ldyStakingAddress);\n }\n\n /**\n * @notice Updates the address of the withdrawer wallet.\n * @param withdrawer_ The address of the new withdrawer wallet.\n */\n function setWithdrawer(address payable withdrawer_) public onlyOwner {\n // Ensure address is not the zero address (pre-processing fees would be lost else)\n require(withdrawer_ != address(0), \"L63\");\n\n // Set new withdrawer wallet's address\n withdrawer = withdrawer_;\n }\n\n /**\n * @notice Updates the address of the fund wallet.\n * @param fund_ The address of the new fund wallet.\n */\n function setFund(address payable fund_) public onlyOwner {\n // Ensure address is not the zero address (deposited tokens would be lost else)\n require(fund_ != address(0), \"L64\");\n\n // Set new fund wallet's address\n fund = fund_;\n }\n\n /**\n * @notice Adds a new contract to the L-Token transfers list.\n * @dev Each time a transfer occurs, the onLTokenTransfer() function of the\n * specified contract will be called.\n * @dev IMPORTANT SECURITY NOTE: This method is not intended to be used with\n * contracts that are not owned by the Ledgity team.\n * @param listenerContract The address of the new transfers listener contract.\n */\n function listenToTransfers(address listenerContract) public onlyOwner {\n transfersListeners.push(ITransfersListener(listenerContract));\n }\n\n /**\n * @notice Removes a contract from the L-Token transfers list.\n * @dev The onLTokenTransfer() function of the specified contract will not be called\n * anymore each time a L-Token transfer occurs.\n * @param listenerContract The address of the listener contract.\n */\n function unlistenToTransfers(address listenerContract) public onlyOwner {\n // Find index of listener contract in transferListeners array\n int256 index = -1;\n uint256 transfersListenersLength = transfersListeners.length;\n for (uint256 i = 0; i < transfersListenersLength; i++) {\n if (address(transfersListeners[i]) == listenerContract) {\n index = int256(i);\n break;\n }\n }\n\n // Revert if given contract wasn't listening to transfers\n require(index > -1, \"L42\");\n\n // Else, remove transfers listener contract from listeners array\n transfersListeners[uint256(index)] = transfersListeners[transfersListenersLength - 1];\n transfersListeners.pop();\n }\n\n /**\n * @notice Retrieves the amount of given account's not yet minted rewards.\n * @dev This is a public implementation of InvestUpgradeable_rewardsOf(). In the\n * context of LToken, this function returns the amount of rewards that have not been\n * distributed/minted yet to the specified account.\n * @dev This is particularly useful for off-chain services to display charts and\n * statistics, as seen in the Ledgity Yield's frontend.\n * @param account The account to check the unminted rewards of.\n * @return The amount of account's unminted rewards.\n */\n function unmintedRewardsOf(address account) public view returns (uint256) {\n return _rewardsOf(account, true);\n }\n\n /**\n * @notice Retrieves the \"real\" balance of an account, i.e., excluding its not yet\n * minted/distributed rewards.\n * @param account The account to check the real balance of.\n * @return The real balance of the account.\n */\n function realBalanceOf(address account) public view returns (uint256) {\n return super.balanceOf(account);\n }\n\n /**\n * @notice Retrieves the total balance of L-Tokens that belong to the account.\n * @dev This is an oOverride of ERC20Upgradeable.balanceOf() that rewards that have\n * not been yet minted to the specified account.\n * @param account The account to check the total balance of.\n * @return The total balance of the account.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return realBalanceOf(account) + unmintedRewardsOf(account);\n }\n\n /**\n * @notice Returns the \"real\" amount of existing L-Tokens, i.e., excluding not yet\n * minted withdrawal fees and L-Tokens currently in the withdrawal queue.\n * @return The real total supply of L-Tokens.\n */\n function realTotalSupply() public view returns (uint256) {\n return super.totalSupply();\n }\n\n /**\n * @notice Retrives the total supply of L-Tokens, including not yet minted withdrawal\n * fees and L-Tokens currently in the withdrawal queue.\n * @return The total supply of L-Tokens.\n */\n function totalSupply() public view override returns (uint256) {\n return realTotalSupply() + totalQueued + unclaimedFees;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address.\n * @dev This override of RecoverableUpgradeable.recoverERC20() prevents the recovered\n * token from being the underlying token.\n * @inheritdoc RecoverableUpgradeable\n */\n function recoverERC20(address tokenAddress, uint256 amount) public override onlyOwner {\n // Ensure the token is not the underlying token\n require(tokenAddress != address(underlying()), \"L43\");\n\n // Proceed to recovery\n super.recoverERC20(tokenAddress, amount);\n }\n\n /**\n * @notice Recovers underlying tokens accidentally sent to the contract.\n * @dev To prevent owner from being able to drain the contract, this function only\n * allows recovering \"unusable\" underlying tokens, i.e., tokens that have not been\n * sent through fund() or deposit() functions.\n */\n function recoverUnderlying() external onlyOwner {\n // Compute the recoverable amount by taking the difference between the contract's\n // balance and the amount of usable underlying tokens\n uint256 recoverableAmount = underlying().balanceOf(address(this)) - usableUnderlyings;\n\n // Revert if there is nothing to recover\n require(recoverableAmount > 0, \"L44\");\n\n // Else, proceed to underlying tokens recovery\n super.recoverERC20(address(underlying()), recoverableAmount);\n }\n\n /**\n * @notice Retrieves the amount of underlying tokens invested by the given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract. In\n * LToken contract, the investment of an account is equal to its real balance.\n * @inheritdoc InvestUpgradeable\n */\n function _investmentOf(address account) internal view override returns (uint256) {\n return realBalanceOf(account);\n }\n\n /**\n * @notice Distributes a specified amount of rewards (in L-Tokens) to a given account.\n * @dev Implementing this function is required by the InvestUpgradeable contract so\n * it can distribute rewards to accounts before each period reset.\n * @dev InvestUpgradeable contract already ensure that amount > 0.\n * @inheritdoc InvestUpgradeable\n */\n function _distributeRewards(address account, uint256 amount) internal override returns (bool) {\n // Inform listeners of the rewards minting\n emit MintedRewardsEvent(account, realBalanceOf(account), amount);\n\n // Mint L-Tokens rewards to account\n _mint(account, amount);\n\n // Return true indicating to InvestUpgradeable that the rewards have been distributed\n return true;\n }\n\n /**\n * @notice Override of ERC20._beforeTokenTransfer() to integrate with InvestUpgradeable.\n * @dev This overriden version ensure that _beforeInvestmentChange() hook is properly\n * called each time an account's balance is going to change.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already included in ERC20BaseUpgradeable._beforeTokenTransfer().\n * @inheritdoc ERC20BaseUpgradeable\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal override(ERC20Upgradeable, ERC20BaseUpgradeable) {\n ERC20BaseUpgradeable._beforeTokenTransfer(from, to, amount);\n\n // Invoke _beforeInvestmentChange() hook for non-zero accounts\n if (from != address(0)) _beforeInvestmentChange(from, true);\n if (to != address(0)) _beforeInvestmentChange(to, true);\n }\n\n /**\n * @notice Override of ERC20._afterTokenTransfer() to notify all transfers listeners.\n * @dev This overriden version will trigger onLTokenTransfer() functions of all\n * transfers listeners.\n * @dev Note: whenNotPaused and notBlacklisted modifiers are not set as they are\n * already checked in _beforeTokenTransfer().\n * @inheritdoc ERC20Upgradeable\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal override {\n super._afterTokenTransfer(from, to, amount);\n\n // If some L-Token have been burned/minted, inform listeners of a TVL change\n if (from == address(0) || to == address(0)) emit TVLChangeEvent(totalSupply());\n\n // Trigger onLTokenTransfer() functions of all the transfers listeners\n for (uint256 i = 0; i < transfersListeners.length; i++) {\n transfersListeners[i].onLTokenTransfer(from, to, amount);\n }\n }\n\n /**\n * @notice Computes the maximum amount of underlying tokens that should be retained\n * by the contract (based on retention rate).\n * @return amount The expected amount of retained underlying tokens.\n */\n function getExpectedRetained() public view returns (uint256 amount) {\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert totalSupply and retentionRate to SUD\n uint256 totalSupplySUD = SUD.fromAmount(totalSupply(), d);\n uint256 retentionRateSUD = SUD.fromRate(retentionRateUD7x3, d);\n\n // Compute and return expected retained amount\n uint256 expectedRetainedSUD = (totalSupplySUD * retentionRateSUD) / SUD.fromInt(100, d);\n return SUD.toAmount(expectedRetainedSUD, d);\n }\n\n /// @notice Transfers underlying tokens exceeding the retention rate to the fund wallet.\n function _transferExceedingToFund() internal {\n // Retrieve the expected amount retained\n uint256 expectedRetained = getExpectedRetained();\n\n // If usable underlyings are less than or equal to expected retained, return\n if (usableUnderlyings <= expectedRetained) return;\n\n // Else, exceeding amount is equal to difference between those values\n uint256 exceedingAmount = usableUnderlyings - expectedRetained;\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= exceedingAmount;\n\n // Transfer the exceeding amount to the fund wallet\n underlying().safeTransfer(fund, exceedingAmount);\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.withdrawTo() that reverts.\n * Use instantWithdrawal() or requestWithdrawal() functions instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function withdrawTo(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L45\");\n }\n\n /**\n * @notice Override of ERC20WrapperUpgradeable.depositFor() that reverts.\n * Use deposit() function instead.\n * @inheritdoc ERC20WrapperUpgradeable\n */\n function depositFor(address account, uint256 amount) public pure override returns (bool) {\n account; // Silence unused variable compiler warning\n amount;\n revert(\"L46\");\n }\n\n /**\n * @notice Allows exchanging some underlying tokens for the same amount of L-Tokens.\n * @param amount The amount of underlying tokens to deposit.\n */\n function deposit(uint256 amount) public whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough underlying tokens to deposit\n require(underlying().balanceOf(_msgSender()) >= amount, \"L47\");\n\n // Update usable underlyings balance accordingly\n usableUnderlyings += amount;\n\n // Inform listeners of the deposit activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Deposit,\n amount,\n amount,\n Status.Success,\n NO_ID\n );\n\n // Receive underlying tokens and mint L-Tokens to the account in a 1:1 ratio\n super.depositFor(_msgSender(), amount);\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Computes fees and net withdrawn amount for a given account withdrawing a\n * given amount.\n * @param account The account initiating the withdrawal.\n * @param amount The amount of the withdrawal.\n */\n function getWithdrawnAmountAndFees(\n address account,\n uint256 amount\n ) public view returns (uint256 withdrawnAmount, uint256 fees) {\n // If the account is eligible to staking tier 2, no fees are applied\n if (ldyStaking.tierOf(account) >= 2) return (amount, 0);\n\n // Cache invested token's decimals number\n uint256 d = SUD.decimalsOf(address(invested()));\n\n // Convert amount and fees rate to SUD\n uint256 amountSUD = SUD.fromAmount(amount, d);\n uint256 feesRateSUD = SUD.fromRate(feesRateUD7x3, d);\n\n // Compute fees and withdrawn amount (initial amount minus fees)\n uint256 feesSUD = (amountSUD * feesRateSUD) / SUD.fromInt(100, d);\n fees = SUD.toAmount(feesSUD, d);\n withdrawnAmount = amount - fees;\n }\n\n /**\n * @notice Allows instaneously exchanging a given amount of L-Tokens for the same\n * amount of underlying tokens. It will fail if the contract currently doesn't hold\n * enough underlying tokens to cover the withdrawal.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestWithdrawal() function otherwise.\n * @param amount The amount L-Tokens to withdraw.\n */\n function instantWithdrawal(uint256 amount) external whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L48\");\n\n // Can the contract cover this withdrawal plus all already queued requests?\n bool cond1 = totalQueued + amount <= usableUnderlyings;\n\n // Is caller eligible to staking tier 2 and the contract can cover this withdrawal?\n bool cond2 = ldyStaking.tierOf(_msgSender()) >= 2 && amount <= usableUnderlyings;\n\n // Revert if conditions are not met for the withdrawal to be processed instantaneously\n if (!(cond1 || cond2)) revert(\"L49\");\n\n // Else, retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(_msgSender(), amount);\n\n // Increase unclaimed fees amount accordingly\n unclaimedFees += fees;\n\n // Decrease usable underlyings balance accordingly\n usableUnderlyings -= withdrawnAmount;\n\n // Inform listeners of this instant withdrawal activity event\n emit ActivityEvent(\n NO_ID,\n _msgSender(),\n Action.Withdraw,\n amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Burn withdrawal fees from the account\n _burn(_msgSender(), fees);\n\n // Burn account's withdrawn L-Tokens and transfer to it underlying tokens in a 1:1 ratio\n super.withdrawTo(_msgSender(), withdrawnAmount);\n }\n\n /**\n * @notice Allows requesting the exchange of a given amount of L-Tokens for the same\n * amount of underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n * @param amount The amount L-Tokens to withdraw.\n */\n function requestWithdrawal(\n uint256 amount\n ) public payable whenNotPaused notBlacklisted(_msgSender()) {\n // Ensure the account has enough L-Tokens to withdraw\n require(amount <= balanceOf(_msgSender()), \"L53\");\n\n // Ensure the requested amount doesn't overflow uint96\n require(amount <= type(uint96).max, \"L54\");\n\n // Ensure the sender attached the pre-paid processing gas fees\n require(msg.value == 0.003 * 10 ** 18, \"L55\");\n\n // Create withdrawal request data\n WithdrawalRequest memory request = WithdrawalRequest({\n account: _msgSender(),\n amount: uint96(amount)\n });\n\n // Will hold the request ID\n uint256 requestId;\n\n // Append request to the withdrawal queue:\n // - At the beginning, if account is eligible to staking tier 2 and cursor is not 0\n if (ldyStaking.tierOf(_msgSender()) >= 2 && withdrawalQueueCursor > 0) {\n withdrawalQueueCursor--;\n requestId = withdrawalQueueCursor;\n withdrawalQueue[requestId] = request;\n }\n // - At the end else\n else {\n withdrawalQueue.push(request);\n requestId = withdrawalQueue.length - 1;\n }\n\n // Increase total amount queued accordingly\n totalQueued += amount;\n\n // Inform listeners of this new queued withdrawal activity event\n emit ActivityEvent(\n int256(requestId),\n _msgSender(),\n Action.Withdraw,\n amount,\n amount,\n Status.Queued,\n NO_ID\n );\n\n // Burn withdrawal L-Tokens amount from account's balance\n _burn(_msgSender(), amount);\n\n // Forward pre-paid processing gas fees to the withdrawer wallet\n (bool sent, ) = withdrawer.call{value: msg.value}(\"\");\n require(sent, \"L56\");\n }\n\n /**\n * @notice Processes queued withdrawal requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n * @dev For further details, see \"LToken > Withdrawals\" section of whitepaper.\n */\n function processQueuedRequests() external onlyWithdrawer whenNotPaused {\n // Accumulators variables, will be written on-chain after the loop\n uint256 cumulatedFees = 0;\n uint256 cumulatedWithdrawnAmount = 0;\n uint256 nextRequestId = withdrawalQueueCursor;\n\n // Cache queue length to avoid multiple SLOADs and avoid infinite loop as big\n // requests are increasing the queue length when moved at the end of the queue.\n uint256 queueLength = withdrawalQueue.length;\n\n // Iterate over requests to be processed\n while (nextRequestId < queueLength) {\n // Stop processing requests if there is not enough gas left to continue the\n // loop and properly end the function call. This prevents an attacker from\n // blocking the withdrawal processing by creating a ton of tiny requests so\n // this function call cannot fit anymore in block gas limit.\n if (gasleft() < 45000) break;\n\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[nextRequestId];\n\n // Skip empty request (processed big requests or cancelled requests)\n if (request.account == address(0)) {}\n //\n // If account has been blacklisted since request emission\n else if (isBlacklisted(request.account)) {\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request in the frozen requests list\n frozenRequests.push(request);\n }\n //\n // Or if request is a big request, move it at the end of the queue for now.\n // This request will be processed manually later using processBigQueuedRequest()\n else if (request.amount > getExpectedRetained() / 2) {\n // Inform listeners of this queued request being moved at the end of the queue\n emit ActivityEvent(\n int256(nextRequestId),\n _msgSender(),\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Moved,\n int256(withdrawalQueue.length)\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Append request at the end of the queue\n withdrawalQueue.push(request);\n }\n //\n // Else, continue request processing\n else {\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Break if the contract doesn't hold enough funds to cover the request\n if (withdrawnAmount > usableUnderlyings - cumulatedWithdrawnAmount) break;\n\n // Accumulate fees and withdrawn amount\n cumulatedFees += fees;\n cumulatedWithdrawnAmount += withdrawnAmount;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(nextRequestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[nextRequestId];\n\n // Transfer underlying tokens to account. Burning L-Tokens is not required\n // as equestWithdrawal() already did it.\n // Security note: Re-entrancy warning are disabled as the request has\n // just been deleted from the queue, it will so be skipped if trying to\n // process it again.\n // slither-disable-next-line reentrancy-no-eth\n underlying().safeTransfer(request.account, withdrawnAmount);\n }\n\n // Increment next request ID\n nextRequestId++;\n }\n\n // Increase unclaimed fees by the amount of cumulated fees\n unclaimedFees += cumulatedFees;\n\n // Decrease usable underlyings by the cumulated amount of withdrawn underlyings\n usableUnderlyings -= cumulatedWithdrawnAmount;\n\n // Decrease total amount queued by the cumulated amount requested\n totalQueued -= cumulatedWithdrawnAmount + cumulatedFees;\n\n // Update new queue cursor\n withdrawalQueueCursor = nextRequestId;\n\n // Retention rate cannot exceeds as the withdrawal decreases both usable\n // underlyings and expected retained amounts by the same number and as the\n // expected retained amount is a subset of usable underlyings amount.\n }\n\n /**\n * @notice Processes a given queued big withdrawal request (one that exceeds half of\n * the retention rate).\n * @dev In contrast to non-big requests processing, this function will uses to fund\n * wallet's balance to fill the request. This allows processing requests that are\n * greater than retention rate without having to exceed this rate on the contract.\n * @param requestId The ID of the big request to process.\n */\n function processBigQueuedRequest(uint256 requestId) external onlyFund whenNotPaused {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure the request is active\n require(request.account != address(0), \"L66\");\n\n // Ensure the request emitter has not been blacklisted since request emission\n require(!isBlacklisted(request.account), \"L50\");\n\n // Ensure this is indeed a big request\n require(request.amount > getExpectedRetained() / 2, \"L51\");\n\n // Retrieve withdrawal fees and net withdrawn amount\n (uint256 withdrawnAmount, uint256 fees) = getWithdrawnAmountAndFees(\n request.account,\n request.amount\n );\n\n // Ensure withdrawn amount can be covered by contract + fund wallet balances\n uint256 fundBalance = underlying().balanceOf(fund);\n require(withdrawnAmount <= usableUnderlyings + fundBalance, \"L52\");\n\n // Increase amount of unclaimed fees accordingly\n unclaimedFees += fees;\n\n // Decrease total queued amount by request amount\n totalQueued -= request.amount;\n\n // Increment queue cursor if request was the next request to be processed\n if (requestId == withdrawalQueueCursor) withdrawalQueueCursor++;\n\n // Inform listeners of this queued withdrawal processing activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n withdrawnAmount,\n Status.Success,\n NO_ID\n );\n\n // Remove request from queue\n delete withdrawalQueue[requestId];\n\n // If fund wallet's balance can cover request, rely on it only\n if (withdrawnAmount <= fundBalance) {\n underlying().safeTransferFrom(_msgSender(), request.account, withdrawnAmount);\n }\n // Else, cover request from both fund wallet and contract balances\n else {\n // Compute amount missing from fund wallet to cover request\n uint256 missingAmount = withdrawnAmount - fundBalance;\n\n // Decrease usable amount of underlying tokens accordingly\n usableUnderlyings -= missingAmount;\n\n // Transfer entire fund balance to request's emitter\n underlying().safeTransferFrom(_msgSender(), request.account, fundBalance);\n\n // Transfer missing amount from contract balance to request emitter\n underlying().safeTransfer(request.account, missingAmount);\n }\n\n // Transfer exceeding underlying tokens to the fund wallet\n _transferExceedingToFund();\n }\n\n /**\n * @notice Cancels a given withdrawal request. The request emitter receive back its\n * L-Tokens and no fees will be charged.\n * @param requestId The ID of the withdrawal request to cancel.\n */\n function cancelWithdrawalRequest(\n uint256 requestId\n ) public whenNotPaused notBlacklisted(_msgSender()) {\n // Retrieve request data\n WithdrawalRequest memory request = withdrawalQueue[requestId];\n\n // Ensure request belongs to caller\n require(_msgSender() == request.account, \"L57\");\n\n // Decrease total amount queued accordingly\n totalQueued -= request.amount;\n\n // Delete the withdrawal request from queue\n delete withdrawalQueue[requestId];\n\n // Inform listeners of this cancelled withdrawal request activity event\n emit ActivityEvent(\n int256(requestId),\n request.account,\n Action.Withdraw,\n request.amount,\n request.amount,\n Status.Cancelled,\n NO_ID\n );\n\n // Mint back L-Tokens to account\n _mint(request.account, uint256(request.amount));\n }\n\n /**\n * @notice Used by the fund wallet to repatriate underlying tokens on the contract\n * whenever those are required to fulfill some withdrawal requests.\n * @dev The function will revert if repatriated amount makes the contract exceeding\n * the retention rate.\n * @param amount The amount of underlying tokens to repatriate.\n */\n function repatriate(uint256 amount) external onlyFund whenNotPaused {\n // Ensure the fund wallet has enough funds to repatriate\n require(amount <= underlying().balanceOf(fund), \"L58\");\n\n // Calculate new contract usable balance\n uint256 newBalance = usableUnderlyings + amount;\n\n // Ensure the new balance doesn't exceed the retention rate\n require(newBalance <= getExpectedRetained(), \"L59\");\n\n // Increase usable underlyings amount by repatriated amount\n usableUnderlyings += amount;\n\n // Transfer amount from fund wallet to contract\n underlying().safeTransferFrom(_msgSender(), address(this), amount);\n }\n\n /// @notice Used by owner to claim fees generated from successful withdrawals.\n function claimFees() external onlyOwner {\n // Ensure there are some fees to claim\n require(unclaimedFees > 0, \"L60\");\n\n // Ensure the contract holds enough underlying tokens to cover fees\n require(usableUnderlyings >= unclaimedFees, \"L61\");\n\n // Decrease usable underlyings amount accordingly\n usableUnderlyings -= unclaimedFees;\n\n // Store fees amount in memory and reset unclaimed fees amount\n uint256 fees = unclaimedFees;\n unclaimedFees = 0;\n\n // Transfer unclaimed fees to owner\n underlying().safeTransfer(owner(), fees);\n }\n}\n" + }, + "contracts/src/PreMining.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {LToken} from \"./LToken.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\n/**\n * @title PreMining\n * @author Lila Rest (https://lila.rest)\n * @custom:security-contact security@ledgity.com\n\n * @notice PreMining pool contract, allowing accounts to lock underlying tokens in a \n * pre-defined L-Token contract, over a given duration (in months), in exchange of \n * vested LDY rewards.\n * \n * @dev Intuition\n * \n * Lifecycle of a lockdrop pool is composed by 3 main phases:\n * 1) Deposit: During this phase, users can lock their underlying tokens.\n * 2) Claim: During this phase, users can claim their LDY rewards.\n * 3) Recovery: During this phase, owner can recover remaining ERC20 on the contract.\n * \n * Transitioning between two phases is manually triggered by contract's owner.\n * To ensure fair usage of this power and prevent potential misuse:\n * - the Recovery phase cannot start before 3 months after the end of rewards vesting,\n * - the Recovery phase cannot start before 3 months after the maximum lock end.\n * \n * Finally, note that this contract proxies main L-Token contract's functions:\n * - lock() --> deposit()\n * - instantUnlock() --> instantWithdrawal()\n * - requestUnlock() --> requestWithdrawal()\n * This design enables users to interact with the PreMining contract in a similar fashion\n * to the L-Token contract.\n * \n * @dev Definitions:\n * - Locker: An account that has locked underlying tokens in the pool.\n * \n * @custom:security-contact security@ledgity.com\n */\ncontract PreMining is Ownable2Step, Pausable {\n using SafeERC20 for IERC20;\n\n /**\n * @notice Represents the lock information of an account.\n * @param amount Amount of underlying tokens locked.\n * @param duration Duration of the lock (in months).\n * @param hasUnlocked Whether the account has unlocked its locked tokens.\n * @param claimedRewards Amount of LDY rewards already claimed.\n * @param lockEndTimestamp Timestamp at which the account's lock ends.\n */\n struct AccountLock {\n uint240 amount;\n uint8 duration;\n bool hasUnlocked;\n uint216 claimedRewards;\n uint40 lockEndTimestamp;\n }\n\n /// @notice Holds the amount of LDY to be distributed to lockers.\n uint256 public immutable maxDistributedLDY;\n\n /// @notice Holds the maximum total amount of L-Tokens that can be locked.\n uint256 public immutable lockedHardCap;\n\n /// @notice Holds the minimum possible lock duration (in months).\n uint8 public immutable minLockDuration;\n\n /// @notice Holds the maximum possible lock duration (in months).\n uint8 public immutable maxLockDuration;\n\n /// @notice Holds the duration of LDY rewards vesting (in months).\n uint8 public immutable vestingDuration;\n\n /// @notice Holds a reference to the locked L-Token contract.\n LToken public immutable lToken;\n\n /// @notice Holds a reference to the L-Token underlying stablecoin.\n IERC20 public immutable underlyingToken;\n\n /// @notice Holds the max pool weight.\n uint256 public immutable maxWeight;\n\n /// @notice Holds a reference to the LDY token contract.\n IERC20 public ldyToken;\n\n /// @notice Holds lockers' participations informations.\n mapping(address => AccountLock) public accountsLocks;\n\n /// @notice Holds the total amount of locked underlying tokens.\n uint256 public totalLocked;\n\n /// @notice Holds whether the Deposit phase has ended.\n bool public hasDepositPhaseEnded;\n\n /// @notice Holds whether the Claim phase has started.\n bool public hasClaimPhaseStarted;\n\n /// @notice Holds whether the Recovery phase has started.\n bool public hasRecoveryPhaseStarted;\n\n /// @notice Holds the timestamp at which the Claim phase started.\n uint256 public claimPhaseStartTimestamp;\n\n /// @notice Holds an ordered queue of accounts that requested to unlock their tokens.\n address[] public unlockRequests;\n\n /// @notice Holds the index of the first request in the queue (a.k.a, next one to be processed).\n uint256 public unlockRequestsCursor;\n\n /// @notice Emitted to inform about a new lock/deposit.\n event Lock(address indexed account, uint256 amount, uint8 duration);\n\n /// @notice Top-level checks and code shared by both unlock functions.\n modifier safeUnlock() {\n // Ensure that the account's lock has ended\n require(accountsLocks[msg.sender].lockEndTimestamp <= block.timestamp, \"L68\");\n\n // Ensure the account hasn't already unlocked its tokens\n require(!accountsLocks[msg.sender].hasUnlocked, \"L69\");\n\n // Ensure the account has something to unlock\n require(accountsLocks[msg.sender].amount > 0, \"L70\");\n\n // Indicate that account has unlocked its tokens\n accountsLocks[msg.sender].hasUnlocked = true;\n _;\n }\n\n /**\n * @notice This constructor function etches the lockdrop terms in immutable states.\n * Ensuring that those terms cannot be modified after deployment.\n * @param lTokenAddress_ Address of the L-Token contract to use.\n * @param maxDistributedLDY_ Amount of LDY to be distributed to lockers.\n * @param lockedHardCap_ Maximum total amount of L-Tokens that can be locked.\n * @param minLockDuration_ Minimum possible lock duration (in months).\n * @param maxLockDuration_ Maximum possible lock duration (in months).\n * @param vestingDuration_ Duration of LDY rewards vesting (in months).\n */\n constructor(\n address lTokenAddress_,\n uint256 maxDistributedLDY_,\n uint256 lockedHardCap_,\n uint8 minLockDuration_,\n uint8 maxLockDuration_,\n uint8 vestingDuration_\n ) {\n // Ensure minLockDuration is at least 1 month\n require(minLockDuration_ >= 1, \"L72\");\n\n // Ensure minLockDuration is not greater than maxLockDuration\n require(minLockDuration_ <= maxLockDuration_, \"L73\");\n\n // Set immutable states\n lToken = LToken(lTokenAddress_);\n underlyingToken = IERC20(address(lToken.underlying()));\n lockedHardCap = lockedHardCap_;\n maxDistributedLDY = maxDistributedLDY_;\n minLockDuration = minLockDuration_;\n maxLockDuration = maxLockDuration_;\n vestingDuration = vestingDuration_;\n maxWeight = lockedHardCap * uint256(maxLockDuration);\n }\n\n /**\n * @notice Public implementation of Pausable's pausing and unpausing functions, but\n * restricted to contract's owner.\n */\n function pause() public onlyOwner {\n _pause();\n }\n\n function unpause() public onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Updates the LDY token contract address.\n * @dev As the first Ledgity Yield lockdrop campaigns will start before the LDY TGE,\n * this function allows the contract's owner to set the LDY token address once it\n * becomes available.\n * @param ldyTokenAddress Address of the LDY token contract.\n */\n function setLDYToken(address ldyTokenAddress) external onlyOwner {\n // Prevent owner from changing the LDY address after Claim phase has started\n require(!hasClaimPhaseStarted, \"L74\");\n\n // Set LDY token address\n ldyToken = IERC20(ldyTokenAddress);\n }\n\n /**\n * @notice Closes the Deposit phase. After calling this function, account won't be\n * able to lock additional underlying tokens anymore.\n */\n function endDepositPhase() external onlyOwner {\n hasDepositPhaseEnded = true;\n }\n\n /**\n * @notice Opens the Claim phase. After calling this function, lockers will be able\n * to start claiming their LDY rewards.\n */\n function startClaimPhase() external onlyOwner {\n // Ensure Claim phase has not already started\n require(!hasClaimPhaseStarted, \"L76\");\n\n // Ensure that LDY token address is available\n require(address(ldyToken) != address(0), \"L77\");\n\n // Set Claim phase as started and store the start timestamp\n hasClaimPhaseStarted = true;\n claimPhaseStartTimestamp = block.timestamp;\n }\n\n /**\n * @notice Opens the Recovery phase. After calling this function, the contract owner\n * will be able to recover remaining ERC20 tokens on the contract.\n * Note that this won't close the Claim phase and lockers will still be able to claim\n * their LDY rewards.\n */\n function startRecoveryPhase() external onlyOwner {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L79\");\n\n // Compute some durations in seconds\n uint256 threeMonthsInSecond = 3 * 30 days;\n uint256 vestingInSecond = uint256(vestingDuration) * 30 days;\n uint256 maxLockInSecond = uint256(maxLockDuration) * 30 days;\n\n // Compute timestamp of vesting end + 3 months\n uint256 afterVestingTimestamp = claimPhaseStartTimestamp +\n vestingInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the end of reward vesting\n // This prevents owner from recovering LDY before lockers can claim their rewards\n require(block.timestamp >= afterVestingTimestamp, \"L80\");\n\n // Compute end of maximum lock + 3 months\n // Note that claimPhaseStartTimestamp is used for simplicity even if it can exist a time\n // span between Deposit and Claim phases.\n uint256 afterMaxLockTimestamp = claimPhaseStartTimestamp +\n maxLockInSecond +\n threeMonthsInSecond;\n\n // Ensure we are at least 3 months after the maximum lock end\n // This prevents owner from recovering underlying tokens before lockers can unlock those\n require(block.timestamp >= afterMaxLockTimestamp, \"L81\");\n\n // Set recovery phase as started\n hasRecoveryPhaseStarted = true;\n }\n\n /**\n * @notice Recovers a specified amount of a given token address. Will revert if\n * recovery phase has not started yet or if the contract doesn't hold enough tokens.\n * @param tokenAddress The address of the token to recover.\n * @param amount The amount of token to recover.\n */\n function recoverERC20(address tokenAddress, uint256 amount) external onlyOwner {\n // Ensure recovery phase has started\n require(hasRecoveryPhaseStarted, \"L82\");\n\n // Create a reference to token's contract\n IERC20 tokenContract = IERC20(tokenAddress);\n\n // Ensure there is enough tokens to recover\n require(tokenContract.balanceOf(address(this)) >= amount, \"L83\");\n\n // Transfer the recovered token amount to the sender (owner)\n tokenContract.safeTransfer(msg.sender, amount);\n }\n\n /**\n * @notice Compute the total amount of LDY rewards that a given account is eligible to.\n * @dev Note: This function neither considers vesting nor already claimed rewards.\n * @param account The account to compute the eligible rewards of.\n * @return The total amount of LDY rewards that the account is eligible to.\n */\n function eligibleRewardsOf(address account) public view returns (uint256) {\n // Compute account's lock weight\n uint256 lockerWeight = accountsLocks[account].amount * accountsLocks[account].duration;\n\n // Compute amount of LDY that this locker is eligible to\n if (maxWeight == 0) return 0;\n else return (maxDistributedLDY * lockerWeight) / maxWeight;\n }\n\n /**\n * @notice Allows locking a specified amount of underlying tokens for a given duration.\n * By locking, an account became eligible to a portion of the distributed LDY rewards.\n * @dev This function proxies LToken.deposit()\n * @dev Lockers can extend their lock duration by calling this function again with a\n * greater duration and 0 as amount.\n * @param amount Amount of underlying tokens to lock.\n * @param duration Duration of the lock (in months).\n */\n function lock(uint256 amount, uint8 duration) external whenNotPaused {\n // Ensure Deposit phase has not ended yet\n require(!hasDepositPhaseEnded, \"L84\");\n\n // Ensure account hasn't already unlocked a past lock\n require(!accountsLocks[msg.sender].hasUnlocked, \"L71\");\n\n // Ensure lock duration is in valid range\n require(duration >= minLockDuration && duration <= maxLockDuration, \"L85\");\n\n // Ensure it won't exceed the hardcap\n require(totalLocked + amount <= uint256(lockedHardCap), \"L86\");\n\n // Increase account's locked amount\n accountsLocks[msg.sender].amount += uint240(amount);\n\n // Increase total locked amount accordingly\n totalLocked += amount;\n\n // Use existing lock duration if greater than the new one\n uint8 existingDuration = accountsLocks[msg.sender].duration;\n uint8 appliedDuration = existingDuration > duration ? existingDuration : duration;\n\n // Update account's lock duration\n accountsLocks[msg.sender].duration = appliedDuration;\n\n // Update account's lock end timestamp\n accountsLocks[msg.sender].lockEndTimestamp = uint40(\n block.timestamp + uint40(appliedDuration) * 30 days\n );\n\n // Emit a Lock event\n emit Lock(msg.sender, amount, appliedDuration);\n\n // If amount is 0, skip deposit\n if (amount == 0) return;\n\n // Transfer underlyingToken from account to contract\n underlyingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n // Deposit USDC in the L-Token contract\n underlyingToken.safeApprove(address(lToken), amount);\n lToken.deposit(amount);\n }\n\n /**\n * @notice Allows the caller to instaneously unlock its locked amount of underlying\n * tokens.\n * @dev In order to save some gas and time to users, frontends should propose this\n * function to users only when it has been verified that it will not revert. They\n * should propose the requestUnlock() function otherwise.\n */\n function instantUnlock() external whenNotPaused safeUnlock {\n // Retrieve underlying tokens from the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.instantWithdrawal(unlockedAmount);\n\n // Transfer underlying tokens back to caller\n underlyingToken.safeTransfer(msg.sender, unlockedAmount);\n }\n\n /**\n * @notice Allows the call to request for the unlocking of its locked amount of\n * underlying tokens. The request will be automatically processed later.\n * @dev The sender must attach 0.003 ETH to pre-pay the future processing gas fees\n * paid by the withdrawer wallet.\n */\n function requestUnlock() external payable whenNotPaused safeUnlock {\n // Put account in the unlock requests queue\n unlockRequests.push(msg.sender);\n\n // Request underlying tokens to the L-Token contract\n uint256 unlockedAmount = accountsLocks[msg.sender].amount;\n lToken.requestWithdrawal{value: msg.value}(unlockedAmount);\n }\n\n /**\n * @notice Processes queued unlock requests until there is else no more requests,\n * else not enough underlying tokens to continue.\n */\n function processUnlockRequests() external onlyOwner {\n // Store the current request ID to process\n uint256 processedId = unlockRequestsCursor;\n\n // Loop over remaining requests\n while (processedId < unlockRequests.length) {\n // Prevent OOG by stopping request processing if there is not enough gas left\n // to continue the loop and properly end the function call.\n if (gasleft() < 45000) break;\n\n // Retrieve the request account\n address unlockAccount = unlockRequests[processedId];\n\n // Retrieve the unlocked amount\n uint256 unlockAmount = accountsLocks[unlockAccount].amount;\n\n // If the request has already been processed, skip it\n if (unlockAccount != address(0)) {\n // If the contract doesn't hold enough underlying tokens to process the request, stop here\n if (underlyingToken.balanceOf(address(this)) < unlockAmount) break;\n\n // Delete the request\n delete unlockRequests[processedId];\n\n // Transfer underlying back to account\n underlyingToken.safeTransfer(unlockAccount, unlockAmount);\n }\n\n // Increment processed request ID\n processedId++;\n }\n\n // Write back the cursor in storage\n unlockRequestsCursor = processedId;\n }\n\n /**\n * @notice Computes the amount of LDY rewards available to claim for a given account.\n * @dev This function considers vesting and already claimed rewards.\n * @param account The account to compute the available rewards of.\n * @return The amount of LDY rewards available to claim.\n */\n function availableToClaim(address account) public view returns (uint256) {\n // Compute total amount of rewards allocated to this locker\n uint256 totalEligibleRewards = eligibleRewardsOf(account);\n\n // Compute vesting duration in seconds\n uint256 vestingInSeconds = uint256(vestingDuration) * 30 days;\n\n // Compute elapsed months since claim phase started, and cap it to vesting duration\n uint256 elapsedTime = block.timestamp - claimPhaseStartTimestamp;\n if (elapsedTime > vestingInSeconds) elapsedTime = vestingInSeconds;\n\n // Compute total available to claim (proportionally to elapsed time)\n uint256 totalAvailableToClaim = (totalEligibleRewards * elapsedTime) / vestingInSeconds;\n\n // Else return net claimable (available minus already claimed)\n return totalAvailableToClaim - accountsLocks[account].claimedRewards;\n }\n\n /// @notice Allows the caller to claim its available LDY rewards.\n function claimRewards() external whenNotPaused {\n // Ensure Claim phase has started\n require(hasClaimPhaseStarted, \"L87\");\n\n // Compute claimable LDY rewards\n uint256 claimableLDY = availableToClaim(msg.sender);\n\n // Increase account claimed amount accordingly\n accountsLocks[msg.sender].claimedRewards += uint216(claimableLDY);\n\n // Transfer rewards to account\n ldyToken.safeTransfer(msg.sender, claimableLDY);\n }\n}\n" + } + }, + "settings": { + "evmVersion": "london", + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/contracts/hardhat/lib/deployLToken.ts b/contracts/hardhat/lib/deployLToken.cts similarity index 100% rename from contracts/hardhat/lib/deployLToken.ts rename to contracts/hardhat/lib/deployLToken.cts diff --git a/tsconfig.json b/tsconfig.json index baba7ff8..e9e9d61e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -42,4 +42,4 @@ ".graphclient/**/*.ts" ], "exclude": ["node_modules"] -} \ No newline at end of file +}