From 199fccd4f8826f602fda4ac4e94bafe703d4457d Mon Sep 17 00:00:00 2001 From: Lila Rest Date: Mon, 26 Feb 2024 01:06:18 +0100 Subject: [PATCH] test: add few missing unit tests, plus a ton of docs improvements --- .gitignore | 2 + .vscode/settings.json | 96 +- README.md | 16 +- contracts/foundry/test/LToken.t.sol | 321 ++- .../test/_helpers/ModifiersExpectations.sol | 4 + .../abstracts/GlobalOwnableUpgradeable.t.sol | 2 +- .../GlobalRestrictableUpgradeable.t.sol | 5 +- .../test/abstracts/InvestUpgradeable.t.sol | 2 +- .../test/abstracts/base/BaseUpgradeable.t.sol | 12 + .../abstracts/base/ERC20BaseUpgradeable.t.sol | 23 + contracts/foundry/test/libs/APRHistory.t.sol | 2 + contracts/foundry/test/libs/SUD.t.sol | 13 +- ..._Implementation_before_Aug_22_upgrade.json | 2496 ----------------- ..._Implementation_before_Aug_22_upgrade.json | 2496 ----------------- contracts/src/DummyLDYStaking.sol | 8 +- contracts/src/GlobalBlacklist.sol | 5 +- contracts/src/GlobalOwner.sol | 2 +- contracts/src/GlobalPause.sol | 2 +- contracts/src/LToken.sol | 19 +- contracts/src/LTokenSignaler.sol | 2 +- .../abstracts/GlobalOwnableUpgradeable.sol | 5 +- .../abstracts/GlobalPausableUpgradeable.sol | 7 +- .../GlobalRestrictableUpgradeable.sol | 7 +- contracts/src/abstracts/InvestUpgradeable.sol | 15 +- .../src/abstracts/RecoverableUpgradeable.sol | 9 +- .../src/abstracts/base/BaseUpgradeable.sol | 4 +- .../abstracts/base/ERC20BaseUpgradeable.sol | 2 +- contracts/src/libs/APRHistory.sol | 18 +- contracts/src/libs/SUD.sol | 30 +- docs/contracts-deployment-upgrade.md | 16 - docs/contracts-verification.md | 6 - docs/deploy-LToken.md | 7 - docs/local-subgraph-development.md | 9 - docs/run-frontend-locally.md | 7 - docs/run-slither-tests.md | 4 - docs/ui.md | 77 - docs/upgrade-safe-libraries.md | 24 - foundry.toml | 6 +- hardhat.config.cts | 12 +- package.json | 2 +- scripts/coverage.sh | 16 + 41 files changed, 507 insertions(+), 5304 deletions(-) delete mode 100644 contracts/hardhat/archive/arbitrum/LUSDC_Implementation_before_Aug_22_upgrade.json delete mode 100644 contracts/hardhat/archive/linea/LUSDC_Implementation_before_Aug_22_upgrade.json delete mode 100644 docs/contracts-deployment-upgrade.md delete mode 100644 docs/contracts-verification.md delete mode 100644 docs/deploy-LToken.md delete mode 100644 docs/local-subgraph-development.md delete mode 100644 docs/run-frontend-locally.md delete mode 100644 docs/run-slither-tests.md delete mode 100644 docs/ui.md delete mode 100644 docs/upgrade-safe-libraries.md create mode 100644 scripts/coverage.sh diff --git a/.gitignore b/.gitignore index 05b5e70d..6714d4b9 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,8 @@ typechain-types contracts/hardhat/cache contracts/hardhat/artifacts +lcov.info + # TheGraph subgraph/build subgraph/generated diff --git a/.vscode/settings.json b/.vscode/settings.json index a1720b45..c64bbfa1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,54 +1,54 @@ { "typescript.tsdk": "node_modules/typescript/lib", "files.exclude": { - "renovate.json": true, - "tsconfig.json": true, - "vercel.json": true, - "postcss.config.js": true, - "next-env.d.ts": true, - "CHANGELOG.md": true, - ".releaserc.json": true, - ".next": true, - ".github": true, - "node_modules": true, - ".eslintrc.json": true, - "package.json": true, - ".gitignore": true, - "next.config.mjs": true, - ".env.local": true, - ".env.local.template": true, - "README.md": true, - "LICENSE": true, - "hardhat.config.ts": true, - ".prettierrc.js": true, - "typechain-types": true, - "hardhat/artifacts": true, - "hardhat/cache": true, - ".graphclient": true, - ".graphclientrc.yml": true, - "wagmi.config.ts": true, - "tailwind.config.js": true, - "hardhat/abis": true, - "build": true, - "foundry.toml": true, - ".gitmodules": true, - "slither.config.json": true, - "slither.db.json": true, - "solc.json": true, - "contracts/foundry/cache": true, - "contracts/foundry/out": true, - "contracts/hardhat/artifacts": true, - "contracts/hardhat/cache": true, - "secrets.json": true, - ".env": true, - "report.md": true, - "postcss.config.cjs": true, - "hardhat.config.cts": true, - "bun.lockb": true, - ".prettierrc.cjs": true, - "env.mjs": true, - "docs/": true, - "scripts/": true + "renovate.json": false, + "tsconfig.json": false, + "vercel.json": false, + "postcss.config.js": false, + "next-env.d.ts": false, + "CHANGELOG.md": false, + ".releaserc.json": false, + ".next": false, + ".github": false, + "node_modules": false, + ".eslintrc.json": false, + "package.json": false, + ".gitignore": false, + "next.config.mjs": false, + ".env.local": false, + ".env.local.template": false, + "README.md": false, + "LICENSE": false, + "hardhat.config.ts": false, + ".prettierrc.js": false, + "typechain-types": false, + "hardhat/artifacts": false, + "hardhat/cache": false, + ".graphclient": false, + ".graphclientrc.yml": false, + "wagmi.config.ts": false, + "tailwind.config.js": false, + "hardhat/abis": false, + "build": false, + "foundry.toml": false, + ".gitmodules": false, + "slither.config.json": false, + "slither.db.json": false, + "solc.json": false, + "contracts/foundry/cache": false, + "contracts/foundry/out": false, + "contracts/hardhat/artifacts": false, + "contracts/hardhat/cache": false, + "secrets.json": false, + ".env": false, + "report.md": false, + "postcss.config.cjs": false, + "hardhat.config.cts": false, + "bun.lockb": false, + ".prettierrc.cjs": false, + "env.mjs": false, + "docs/": false, + "scripts/": false }, // Required because of a bug with pnpm and prettier plugins. // See: https://github.com/prettier-solidity/prettier-plugin-solidity#pnpm diff --git a/README.md b/README.md index 3359e9a1..26d0ae9c 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -![](https://github.com/LedgityLabs/dapp/blob/main/src/app/twitter-image.jpg?raw=true) +![](https://github.com/LedgityLabs/LedgityYield/blob/main/src/app/twitter-image.jpg?raw=true) + +# Introduction + +**Ledgity Yield** is a protocol that provides stablecoins holders with a stable and scalable on-chain treasury management solution, backed by Real World Assets (RWA). + +The protocol currently offers **7% APR** to USDC holders, on Linea and Arbitrum chains. However, it tends to be deployed on most EVM chains and to support all the major stablecoins. + +#### [Open the app frontend](https://ledgity.finance/) 💻 + +# Documentation + +You can browse our high-level public documentation at [https://docs.ledgity.finance](https://docs.ledgity.finance). + +If you are interested in the technical documentaton of this codebase, please contact [@LilaRest](https://t.me/LilaRest) on Telegram or drop us an email at [contact@ledgity.com](mailto:contact@ledgity.com). diff --git a/contracts/foundry/test/LToken.t.sol b/contracts/foundry/test/LToken.t.sol index 8382988a..d3eed332 100644 --- a/contracts/foundry/test/LToken.t.sol +++ b/contracts/foundry/test/LToken.t.sol @@ -117,6 +117,17 @@ contract TestedContract is LToken { function public_withdrawalQueueCursor() public view returns (uint256) { return withdrawalQueueCursor; } + + function public_frozenRequestsLength() public view returns (uint256) { + return frozenRequests.length; + } +} + +// Contract used to simulate a failing ETH transfer +contract FailingReceiver { + fallback() external payable { + revert("Failing intentionally"); + } } contract Tests is Test, ModifiersExpectations { @@ -264,6 +275,17 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.retentionRateUD7x3(), 10_000); } + // ========================= + // === paused() function === + function test_paused_1() public { + console.log("Should return state of the global pause contract"); + assertEq(tested.paused(), false); + globalPause.pause(); + assertEq(tested.paused(), true); + globalPause.unpause(); + assertEq(tested.paused(), false); + } + // =============================== // === onlyWithdrawer modifier === function testFuzz_onlyWithdrawer_1(address account) public { @@ -575,8 +597,28 @@ contract Tests is Test, ModifiersExpectations { // ================================ // === realBalanceOf() function === - // No tests needed as it simply proxies super.balanceOf() - // Low priority TODO: Add mirror tests for future safety + function testFuzz_realBalance_1(uint16 aprUD7x3, address account, uint256 amount) public { + console.log("Should mirror changes in super.balanceOf"); + + // Set a first random APR + tested.setAPR(aprUD7x3); + + // Assert that accounts are different, aren't zero address nor the contract address + vm.assume(account != address(0)); + vm.assume(account != address(tested)); + + // Cap amount to [2, 100T] + amount = bound(amount, 2, 100_000_000_000_000 * 10 ** underlyingToken.decimals()); + + // Give some L-Tokens to account1 + deal(address(underlyingToken), account, amount, true); + vm.startPrank(account); + underlyingToken.approve(address(tested), amount); + tested.deposit(amount); + vm.stopPrank(); + + assertEq(tested.realBalanceOf(account), amount); + } // ============================ // === balanceOf() function === @@ -2334,7 +2376,7 @@ contract Tests is Test, ModifiersExpectations { accountBase = uint160(bound(accountBase, 1, type(uint160).max - numberOfRequests)); // Get the interval of blacklisted requests - uint256 blacklistInterval = bound(randomBlacklistSeed, 1, 5); + uint256 blacklistInterval = bound(randomBlacklistSeed, 1, numberOfRequests); // Create random number of requests, and blacklist some of them uint256[50] memory blacklistedRequestsIds; @@ -2396,11 +2438,101 @@ contract Tests is Test, ModifiersExpectations { assertEq(underlyingToken.balanceOf(account), 0); } + // Assert that blacklisted addresses' requests are well in the frozen requests + assertGt(tested.public_frozenRequestsLength(), 0); + assertEq(blacklistedRequestsIdsLength, tested.public_frozenRequestsLength()); + // Assert that the cumulated frozen amount remains queued assertEq(tested.totalQueued(), blacklistedRequestsIdsLength * requestAmount); } function testFuzz_processQueuedRequests_6( + uint8 decimals, + uint16 aprUD7x3, + uint256 totalDeposited + ) public { + console.log("Should silently a big request at the end of the queue"); + + // Set random underlying token decimals in [0, 18] + decimals = uint8(bound(decimals, 0, 18)); + underlyingToken.setDecimals(decimals); + + // Set first random APR + tested.setAPR(aprUD7x3); + + // Set retention rate to 10% + tested.tool_setRetentionRate(uint32(10 * 10 ** 3)); + + // Set no fees + tested.setFeesRate(0); + + // Cap totalDeposited to uint96.max which is the maximum amount of underlying tokens that can be requested at once + // totalDeposited = bound(totalDeposited, 1, type(uint96).max - 30); + totalDeposited = 1_000 * 10 ** decimals; + + // Split total deposited in 90%, 8% and 2%, 8% will be used to create a big request, and 2% to create a small requests + uint256 baseTVLAmount = (totalDeposited * 90) / 100; + uint256 bigRequestAmount = (totalDeposited * 9) / 100; + uint256 smallRequestAmount = (totalDeposited * 1) / 100; + + // Create three depositors for each amount + address baseTVLDepositor = address(1234); + address bigRequestDepositor = address(4321); + address smallRequestDepositor = address(1342); + + // Deposit base TVL amount + deal(address(underlyingToken), baseTVLDepositor, baseTVLAmount, true); + vm.startPrank(baseTVLDepositor); + underlyingToken.approve(address(tested), baseTVLAmount); + tested.deposit(baseTVLAmount); + vm.stopPrank(); + + // Deposit big request amount + deal(address(underlyingToken), bigRequestDepositor, bigRequestAmount, true); + vm.startPrank(bigRequestDepositor); + underlyingToken.approve(address(tested), bigRequestAmount); + tested.deposit(bigRequestAmount); + vm.stopPrank(); + + // Deposit small request amount + deal(address(underlyingToken), smallRequestDepositor, smallRequestAmount, true); + vm.startPrank(smallRequestDepositor); + underlyingToken.approve(address(tested), smallRequestAmount); + tested.deposit(smallRequestAmount); + vm.stopPrank(); + + // Assert L-Token supply is equal to total deposited amount + assertEq(tested.totalSupply(), totalDeposited); + + uint256 processingFees = 0.003 ether; + // Request withdrawal of small amount + deal(smallRequestDepositor, processingFees); + vm.prank(smallRequestDepositor); + tested.requestWithdrawal{value: processingFees}(smallRequestAmount); + + // Request withdrawal of big amount + deal(bigRequestDepositor, processingFees); + vm.prank(bigRequestDepositor); + tested.requestWithdrawal{value: processingFees}(bigRequestAmount); + + // Store queue and cursor length for later comparison + uint256 oldQueueLength = tested.public_withdrawalQueueLength(); + + // Assert that queue length is equal to 2 + assertEq(tested.public_withdrawalQueueLength(), 2); + + // Proceed to batch queued withdraw + vm.prank(withdrawerWallet); + tested.processQueuedRequests(); + + // Assert that queue length have increase by 1, meaning that the big request has been deplaced at the end of the queue + assertEq(tested.public_withdrawalQueueLength(), oldQueueLength + 1); + + // Assert that the cursor is equal to length meaning that the non-big requests has been processed + assertEq(tested.withdrawalQueueCursor(), oldQueueLength); + } + + function testFuzz_processQueuedRequests_7( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2408,7 +2540,7 @@ contract Tests is Test, ModifiersExpectations { uint160 accountBase ) public { console.log( - "Should don't change any state if doesn't hold enough fund to cover first next request" + "Shouldn't change any state if doesn't hold enough fund to cover first next request" ); // Set random underlying token decimals in [0, 18] @@ -2473,7 +2605,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.totalQueued(), oldTotalQueued); } - function testFuzz_processQueuedRequests_7( + function testFuzz_processQueuedRequests_8( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2551,7 +2683,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.totalQueued(), expectedStillQueued); } - function testFuzz_processQueuedRequests_8( + function testFuzz_processQueuedRequests_9( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2643,7 +2775,7 @@ contract Tests is Test, ModifiersExpectations { } } - function testFuzz_processQueuedRequests_9( + function testFuzz_processQueuedRequests_10( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2723,7 +2855,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.withdrawalQueueCursor(), oldQueueLength); } - function testFuzz_processQueuedRequests_10( + function testFuzz_processQueuedRequests_11( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2809,7 +2941,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.unclaimedFees(), expectedUnclaimedFees); } - function testFuzz_processQueuedRequests_11( + function testFuzz_processQueuedRequests_12( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2895,7 +3027,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.usableUnderlyings(), oldUsableUnderlyings - expectedDecrease); } - function testFuzz_processQueuedRequests_12( + function testFuzz_processQueuedRequests_13( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -2975,7 +3107,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.totalQueued(), oldTotalQueued - expectedDecrease); } - function testFuzz_processQueuedRequests_13( + function testFuzz_processQueuedRequests_14( uint8 decimals, uint16 aprUD7x3, uint8 numberOfRequests, @@ -3044,7 +3176,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.withdrawalQueueCursor(), tested.public_withdrawalQueueLength()); } - function test_processQueuedRequests_14() public { + function test_processQueuedRequests_15() public { console.log("Should never revert from out of gas and properly end instead"); // Set decimals to 18 @@ -3119,6 +3251,62 @@ contract Tests is Test, ModifiersExpectations { uint32 retentionRateUD7x3, uint16 feesRateUD7x3, uint256 amount + ) public { + console.log("Should revert if request already processed or cancelled (inactive)"); + + // Set random underlying token decimals in [0, 18] + decimals = uint8(bound(decimals, 0, 18)); + underlyingToken.setDecimals(decimals); + + // Ensure account are neither the zero address nor the L-Token contract + vm.assume(account != address(0)); + vm.assume(account != address(tested)); + + // Set first random APR + tested.setAPR(aprUD7x3); + + // Cap retention rate to 100% + retentionRateUD7x3 = uint32(bound(retentionRateUD7x3, 0, 100 * 10 ** 3)); + + // Set random retention rate + tested.tool_setRetentionRate(retentionRateUD7x3); + + // Set random fees rate + tested.setFeesRate(feesRateUD7x3); + + // Prevent amount from overflowing max withdrawal request amount + amount = bound(amount, 1, type(uint96).max); + + // Deposit random amount + deal(address(underlyingToken), account, amount, true); + vm.startPrank(account); + underlyingToken.approve(address(tested), amount); + tested.deposit(amount); + vm.stopPrank(); + + // Request withdrawal for the big amount + uint256 processingFees = 0.003 ether; + deal(account, processingFees); + vm.prank(account); + tested.requestWithdrawal{value: processingFees}(amount); + + // Cancel request + vm.prank(account); + tested.cancelWithdrawalRequest(0); + + // Expect error when trying to process the inactive queued withdrawal + vm.expectRevert(bytes("L66")); + vm.prank(address(fundWallet)); + tested.processBigQueuedRequest(0); + } + + function testFuzz_processBigQueuedRequest_4( + uint8 decimals, + address account, + uint16 aprUD7x3, + uint32 retentionRateUD7x3, + uint16 feesRateUD7x3, + uint256 amount ) public { console.log("Should revert if request emitter has been blacklisted since emission"); @@ -3167,7 +3355,7 @@ contract Tests is Test, ModifiersExpectations { tested.processBigQueuedRequest(0); } - function testFuzz_processBigQueuedRequest_4( + function testFuzz_processBigQueuedRequest_5( uint8 decimals, address account, uint16 aprUD7x3, @@ -3223,7 +3411,7 @@ contract Tests is Test, ModifiersExpectations { tested.processBigQueuedRequest(0); } - function testFuzz_processBigQueuedRequest_5( + function testFuzz_processBigQueuedRequest_6( uint8 decimals, address account, uint16 aprUD7x3, @@ -3295,7 +3483,7 @@ contract Tests is Test, ModifiersExpectations { vm.stopPrank(); } - function testFuzz_processBigQueuedRequest_6( + function testFuzz_processBigQueuedRequest_7( uint8 decimals, address account, uint16 aprUD7x3, @@ -3369,7 +3557,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(underlyingToken.balanceOf(account), oldAccountBalance + withdrawnAmount); } - function testFuzz_processBigQueuedRequest_7( + function testFuzz_processBigQueuedRequest_8( uint8 decimals, address account, uint16 aprUD7x3, @@ -3440,7 +3628,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(underlyingToken.balanceOf(account), amount); } - function testFuzz_processBigQueuedRequest_8( + function testFuzz_processBigQueuedRequest_9( uint8 decimals, address account, uint16 aprUD7x3, @@ -3497,7 +3685,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.unclaimedFees(), expectedFees); } - function testFuzz_processBigQueuedRequest_9( + function testFuzz_processBigQueuedRequest_10( uint8 decimals, address account, uint16 aprUD7x3, @@ -3556,7 +3744,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.totalQueued(), oldTotalQueued - amount); } - function testFuzz_processBigQueuedRequest_10( + function testFuzz_processBigQueuedRequest_11( uint8 decimals, address account, uint16 aprUD7x3, @@ -3966,16 +4154,6 @@ contract Tests is Test, ModifiersExpectations { tested.requestWithdrawal{value: processingFees}(requestedAmount1); vm.stopPrank(); - // // Ensure account 2 is elligible to staking tier 2 - // uint256 tier2Amount = 10; - // deal(address(ldyToken), account2, tier2Amount, true); - // ldyStaking.setTier(2, tier2Amount); - // vm.startPrank(account2); - // ldyToken.approve(address(ldyStaking), tier2Amount); - // ldyStaking.stake(uint216(tier2Amount)); - // vm.stopPrank(); - // assertEq(ldyStaking.tierOf(account2), 2); - // Add address to dummy LDYStaking high tier addresses ldyStaking.setHighTierAccount(account2, true); @@ -4126,6 +4304,91 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.totalQueued(), requestedAmount); } + function testFuzz_requestWithdrawal_12( + uint8 decimals, + address account, + uint16 aprUD7x3, + uint256 requestedAmount + ) public { + console.log("Should properly transfer processing fees to Withdrawer"); + // Set random underlying token decimals in [0, 18] + decimals = uint8(bound(decimals, 0, 18)); + underlyingToken.setDecimals(decimals); + + // Ensure account is not the zero address + vm.assume(account != address(0)); + vm.assume(account != address(tested)); + + // Set first random APR + tested.setAPR(aprUD7x3); + + // Cap requested amount to max withdrawal request amount + requestedAmount = bound(requestedAmount, 1, type(uint96).max); + + // Deposit requested amount + deal(address(underlyingToken), account, requestedAmount, true); + vm.startPrank(account); + underlyingToken.approve(address(tested), requestedAmount); + tested.deposit(requestedAmount); + vm.stopPrank(); + + // Mint processing fees to account + uint256 processingFees = 0.003 ether; + deal(account, processingFees); + + // Assert that Withdrawer Ether balance is 0 + assertEq(withdrawerWallet.balance, 0); + + // Request withdrawal + vm.prank(account); + tested.requestWithdrawal{value: processingFees}(requestedAmount); + + // Assert that Withdrawer Ether balance is now 0.003ETH + assertEq(withdrawerWallet.balance, processingFees); + } + + function testFuzz_requestWithdrawal_13( + uint8 decimals, + address account, + uint16 aprUD7x3, + uint256 requestedAmount + ) public { + console.log("Should properly revert if transfer processing fees to Withdrawer fails"); + // Set random underlying token decimals in [0, 18] + decimals = uint8(bound(decimals, 0, 18)); + underlyingToken.setDecimals(decimals); + + // Ensure account is not the zero address + vm.assume(account != address(0)); + vm.assume(account != address(tested)); + + // Set first random APR + tested.setAPR(aprUD7x3); + + // Cap requested amount to max withdrawal request amount + requestedAmount = bound(requestedAmount, 1, type(uint96).max); + + // Deposit requested amount + deal(address(underlyingToken), account, requestedAmount, true); + vm.startPrank(account); + underlyingToken.approve(address(tested), requestedAmount); + tested.deposit(requestedAmount); + vm.stopPrank(); + + // Mint processing fees to account + uint256 processingFees = 0.003 ether; + deal(account, processingFees); + + // Set withdrawer to a contract that reverts on receive + FailingReceiver failingWithdrawer = new FailingReceiver(); + tested.setWithdrawer(payable(address(failingWithdrawer))); + + // Request withdrawal + vm.expectRevert(bytes("L56")); + vm.prank(account); + tested.requestWithdrawal{value: processingFees}(requestedAmount); + } + // ==================================== // === cancelWithdrawalRequest() function === function testFuzz_cancelWithdrawalRequest_1(address account, uint256 requestId) public { diff --git a/contracts/foundry/test/_helpers/ModifiersExpectations.sol b/contracts/foundry/test/_helpers/ModifiersExpectations.sol index 504a0a04..2b83bd37 100644 --- a/contracts/foundry/test/_helpers/ModifiersExpectations.sol +++ b/contracts/foundry/test/_helpers/ModifiersExpectations.sol @@ -15,4 +15,8 @@ contract ModifiersExpectations is Test { function expectRevertRestricted() public { vm.expectRevert(bytes("L9")); } + + // Trick to exclude this contract from coverage report + // See: https://github.com/foundry-rs/foundry/issues/2988#issuecomment-1437784542 + function test() public {} } diff --git a/contracts/foundry/test/abstracts/GlobalOwnableUpgradeable.t.sol b/contracts/foundry/test/abstracts/GlobalOwnableUpgradeable.t.sol index ca681bd7..983e308b 100644 --- a/contracts/foundry/test/abstracts/GlobalOwnableUpgradeable.t.sol +++ b/contracts/foundry/test/abstracts/GlobalOwnableUpgradeable.t.sol @@ -67,7 +67,7 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.owner(), address(1234)); } - // ============================ + // ========================== // === onlyOwner modifier === function test_onlyOwner_1() public { console.log("Should allow calls from owner"); diff --git a/contracts/foundry/test/abstracts/GlobalRestrictableUpgradeable.t.sol b/contracts/foundry/test/abstracts/GlobalRestrictableUpgradeable.t.sol index 9ba121a1..4ac426fc 100644 --- a/contracts/foundry/test/abstracts/GlobalRestrictableUpgradeable.t.sol +++ b/contracts/foundry/test/abstracts/GlobalRestrictableUpgradeable.t.sol @@ -86,7 +86,10 @@ contract Tests is Test, ModifiersExpectations { // === isBlacklisted() function === function test_isBlacklisted_1() public { console.log("Should mirror globalBlacklist.isBlacklisted()"); - assertEq(tested.public_isBlacklisted(address(1)), globalBlacklist.isBlacklisted(address(1))); + assertEq( + tested.public_isBlacklisted(address(1)), + globalBlacklist.isBlacklisted(address(1)) + ); // Blacklist address(1) to ensure that tested.isBlacklisted() indeed mirrors globalBlacklist.isBlacklisted() assertEq(tested.public_isBlacklisted(address(1)), false); diff --git a/contracts/foundry/test/abstracts/InvestUpgradeable.t.sol b/contracts/foundry/test/abstracts/InvestUpgradeable.t.sol index 8b1382d5..70aec5fc 100644 --- a/contracts/foundry/test/abstracts/InvestUpgradeable.t.sol +++ b/contracts/foundry/test/abstracts/InvestUpgradeable.t.sol @@ -93,7 +93,7 @@ contract TestedContract is InvestUpgradeable { } function public_distributeRewards(address account, uint256 amount) public returns (bool) { - return _distributeRewards(account, amount); + return InvestUpgradeable._distributeRewards(account, amount); } function public_calculatePeriodRewards( diff --git a/contracts/foundry/test/abstracts/base/BaseUpgradeable.t.sol b/contracts/foundry/test/abstracts/base/BaseUpgradeable.t.sol index 2eda2588..f5ab4d5d 100644 --- a/contracts/foundry/test/abstracts/base/BaseUpgradeable.t.sol +++ b/contracts/foundry/test/abstracts/base/BaseUpgradeable.t.sol @@ -23,6 +23,10 @@ contract TestedContract is BaseUpgradeable { function public_authorizeUpgrade(address newImplementation) public { _authorizeUpgrade(newImplementation); } + + function public___Base_init_unchained() public { + __Base_init_unchained(); + } } contract Tests is Test, ModifiersExpectations { @@ -92,4 +96,12 @@ contract Tests is Test, ModifiersExpectations { expectRevertOnlyOwner(); tested.public_authorizeUpgrade(address(0)); } + + // ======================================== + // === __Base_init_unchained() function === + function test___Base_init_unchained_1() public { + console.log("Should revert if called by after initialization"); + vm.expectRevert(bytes("Initializable: contract is not initializing")); + tested.public___Base_init_unchained(); + } } diff --git a/contracts/foundry/test/abstracts/base/ERC20BaseUpgradeable.t.sol b/contracts/foundry/test/abstracts/base/ERC20BaseUpgradeable.t.sol index 53afc495..fcf44a43 100644 --- a/contracts/foundry/test/abstracts/base/ERC20BaseUpgradeable.t.sol +++ b/contracts/foundry/test/abstracts/base/ERC20BaseUpgradeable.t.sol @@ -28,6 +28,10 @@ contract TestedContract is ERC20BaseUpgradeable { function public_beforeTokenTransfer(address from, address to, uint256 amount) public { _beforeTokenTransfer(from, to, amount); } + + function public___ERC20Base_init_unchained() public { + __ERC20Base_init_unchained(); + } } contract Tests is Test, ModifiersExpectations { @@ -101,6 +105,17 @@ contract Tests is Test, ModifiersExpectations { assertEq(tested.name(), nameAtInitTime); } + // ========================= + // === paused() function === + function test_paused_1() public { + console.log("Should return state of the global pause contract"); + assertEq(tested.paused(), false); + globalPause.pause(); + assertEq(tested.paused(), true); + globalPause.unpause(); + assertEq(tested.paused(), false); + } + // ============================== // === _beforeTokenTransfer() === function testFuzz_beforeTokenTransfer_1(address from, address to, uint256 amount) public { @@ -139,4 +154,12 @@ contract Tests is Test, ModifiersExpectations { console.log("Shouldn't revert else"); tested.public_beforeTokenTransfer(from, to, amount); } + + // ============================================ + // === __ERC20Base_init_unchained() function === + function test___ERC20Base_init_unchained_1() public { + console.log("Should revert if called by after initialization"); + vm.expectRevert(bytes("Initializable: contract is not initializing")); + tested.public___ERC20Base_init_unchained(); + } } diff --git a/contracts/foundry/test/libs/APRHistory.t.sol b/contracts/foundry/test/libs/APRHistory.t.sol index 5712db97..cf1b72c7 100644 --- a/contracts/foundry/test/libs/APRHistory.t.sol +++ b/contracts/foundry/test/libs/APRHistory.t.sol @@ -7,6 +7,8 @@ import {APRHistory as APRH} from "../../../src/libs/APRHistory.sol"; contract Tests is Test { APRH.Pack[] packs; + function setUp() public {} + /** * @dev This function populate given number of packs with dummy data to the * array of packs. Note that dummy data are unique per pack and so can diff --git a/contracts/foundry/test/libs/SUD.t.sol b/contracts/foundry/test/libs/SUD.t.sol index 088e7e21..47ed0acf 100644 --- a/contracts/foundry/test/libs/SUD.t.sol +++ b/contracts/foundry/test/libs/SUD.t.sol @@ -5,6 +5,8 @@ import "../../lib/forge-std/src/Test.sol"; import {SUD} from "../../../src/libs/SUD.sol"; import {GenericERC20} from "../../../src/GenericERC20.sol"; +import {ModifiersExpectations} from "../_helpers/ModifiersExpectations.sol"; + contract Tests is Test { // ============================= // === decimalsOf() function === @@ -82,9 +84,7 @@ contract Tests is Test { // =========================== // === toAmount() function === function testFuzz_toAmount_1(uint8 decimals, uint256 nSUD) public { - console.log( - "Should return convert an UD71x6 to amount if decimals <3 (non-underflow cases)" - ); + console.log("Should convert an UD71x6 to amount if decimals <3 (non-underflow cases)"); // Bound decimals to [0, 2] decimals = uint8(bound(decimals, 0, 2)); @@ -201,7 +201,7 @@ contract Tests is Test { // ========================= // === toRate() function === function testFuzz_toRate_1(uint8 decimals, uint256 nSUD) public { - console.log("Should return convert an UD71x6 to rate if decimals <3 (non-underflow cases)"); + console.log("Should convert an UD71x6 to rate if decimals <3 (non-underflow cases)"); // Bound decimals to [0, 2] decimals = uint8(bound(decimals, 0, 2)); @@ -311,14 +311,13 @@ contract Tests is Test { // Assert that it reverts vm.expectRevert(stdError.arithmeticError); SUD.fromInt(n, decimals); + SUD.toInt(n, decimals); } // ========================= // === toInt() function === function testFuzz_toInt_1(uint8 decimals, uint256 n) public { - console.log( - "Should return convert an UD71x6 to integer if decimals <3 (non-underflow cases)" - ); + console.log("Should convert an UD71x6 to integer if decimals <3 (non-underflow cases)"); // Bound decimals to [0, 2] decimals = uint8(bound(decimals, 0, 2)); diff --git a/contracts/hardhat/archive/arbitrum/LUSDC_Implementation_before_Aug_22_upgrade.json b/contracts/hardhat/archive/arbitrum/LUSDC_Implementation_before_Aug_22_upgrade.json deleted file mode 100644 index d244cfd8..00000000 --- a/contracts/hardhat/archive/arbitrum/LUSDC_Implementation_before_Aug_22_upgrade.json +++ /dev/null @@ -1,2496 +0,0 @@ -{ - "address": "0xA3B0dbA08B0e83Aa6DBcf2fB11eAFb209C84A21F", - "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" - } - ], - "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" - } - ], - "transactionHash": "0xecc3733b6077b7ffd71b34ecccea45978b83733a9ff6fc88beb5f0a079572477", - "receipt": { - "to": null, - "from": "0x9644fFCE92Ff305f14AF9aCD71c7ccbBE6478023", - "contractAddress": "0xA3B0dbA08B0e83Aa6DBcf2fB11eAFb209C84A21F", - "transactionIndex": 1, - "gasUsed": "51096479", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000040000002000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000", - "blockHash": "0x9a05e77125275309b30dd18334417692989d2d3cd57b4cf76acac03f6f41a72d", - "transactionHash": "0xecc3733b6077b7ffd71b34ecccea45978b83733a9ff6fc88beb5f0a079572477", - "logs": [ - { - "transactionIndex": 1, - "blockNumber": 121988712, - "transactionHash": "0xecc3733b6077b7ffd71b34ecccea45978b83733a9ff6fc88beb5f0a079572477", - "address": "0xA3B0dbA08B0e83Aa6DBcf2fB11eAFb209C84A21F", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], - "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", - "logIndex": 0, - "blockHash": "0x9a05e77125275309b30dd18334417692989d2d3cd57b4cf76acac03f6f41a72d" - } - ], - "blockNumber": 121988712, - "cumulativeGasUsed": "51096479", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "5c79fe53028b0d481f9283fd175451bf", - "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\"}],\"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)\":{\"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.\",\"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)\":{\"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\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Replacement of the LDYStaking until the $LDY token is available and the real\\n * LDYStaking contract 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 {\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * ellgible to any LDY staking tier.\\n * @param account @\\n */\\n function tierOf(address account) public pure returns (uint256 tier) {\\n account; // Silence unused variable compiler warning\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x8cd4bd13add4048231adb6e74adaecc3958918ae85fd22de106fce63ec806a5e\",\"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 }\\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.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 );\\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\",\"keccak256\":\"0x35bcf57f7debb63a1be92701efc49e806475c124e678235bb84939f4b682da33\",\"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": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615ef16200011f6000396000818161142301528181611463015281816118b6015281816118f601526119890152615ef16000f3fe6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061540d565b60405180910390f35b34801561041557600080fd5b50610429610424366004615455565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615481565b610cd5565b005b34801561046757600080fd5b50610459610476366004615481565b610d41565b34801561048757600080fd5b5061045961049636600461549e565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f0366004615455565b611037565b34801561050157600080fd5b5061042961051036600461550f565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b50610429610545366004615455565b6113de565b34801561055657600080fd5b5061055f61140f565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615481565b611419565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e5366004615455565b6114f8565b3480156105f657600080fd5b506105b2610605366004615455565b61151a565b34801561061657600080fd5b50610459610625366004615550565b611553565b34801561063657600080fd5b50610459610645366004615550565b611743565b610459610658366004615601565b6118ac565b34801561066957600080fd5b506104b061197c565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a4366004615550565b611a2f565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611a6b565b3480156106f157600080fd5b50610459610700366004615481565b611a75565b34801561071157600080fd5b506104596107203660046156a4565b611bcc565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615481565b611c7d565b34801561077057600080fd5b50610459611c9b565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c2366004615550565b611cd1565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b50610459610801366004615550565b612089565b34801561081257600080fd5b50610459610821366004615455565b61220d565b34801561083257600080fd5b506105b2610841366004615481565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b2612272565b34801561087e57600080fd5b5061045961088d3660046156c1565b6122e1565b34801561089e57600080fd5b506103f3612518565b3480156108b357600080fd5b506104b06108c2366004615481565b612527565b3480156108d357600080fd5b506104596108e2366004615481565b612545565b6104596108f5366004615550565b6125a0565b34801561090657600080fd5b50610429610915366004615455565b612903565b34801561092657600080fd5b50610459610935366004615481565b612989565b34801561094657600080fd5b506104596109553660046156c1565b6129b4565b34801561096657600080fd5b50610429610975366004615455565b612cea565b34801561098657600080fd5b50610459612cf8565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb366004615550565b612de1565b3480156109dc57600080fd5b506109f06109eb366004615455565b612f34565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a20366004615550565b613050565b348015610a3157600080fd5b50610a3a613061565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615481565b6130d9565b348015610af357600080fd5b506104596130e6565b348015610b0857600080fd5b506104b06131a7565b348015610b1d57600080fd5b506104b0610b2c3660046156c1565b61322e565b348015610b3d57600080fd5b50610459610b4c36600461570c565b613259565b348015610b5d57600080fd5b506105b2610b6c366004615550565b613288565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b06132b3565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615481565b6132be565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461570c565b6132f3565b6060609a8054610c3890615729565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6490615729565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc9818585613360565b60019150505b92915050565b610cdd613484565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613484565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed0919081019061575d565b9050610f1d87878784604051602001610ee991906157d4565b60405160208183030381529060405285604051602001610f099190615804565b6040516020818303038152906040526134e5565b610f2683613529565b610f2f30613559565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f73612272565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c612272565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e6132b3565b6110289190615843565b6110329190615843565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613603565b61108185858561367d565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e0613839565b610300546102ff5460009182915b808210156113815761afc85a106113815760006102ff838154811061111557611115615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925291501561136e57805161116490613881565b156111e6576102ff838154811061117d5761117d615856565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa49091015561136e565b60026111f06131a7565b6111fa919061586c565b81602001516001600160601b0316111561128b576102ff838154811061122257611222615856565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9091015561136e565b6000806112a9836000015184602001516001600160601b0316612f34565b91509150856102fe546112bc919061588e565b8211156112cb57505050611381565b6112d58188615843565b96506112e18287615843565b9550600183600001516001600160a01b031686600080516020615e75833981519152866020015186600260405161131a939291906158c3565b60405180910390a46102ff858154811061133657611336615856565b6000918252602082200155825161136b908361135b6102c6546001600160a01b031690565b6001600160a01b031691906138f1565b50505b82611378816158e7565b935050506110ee565b836102fc60008282546113949190615843565b92505081905550826102fe60008282546113ae919061588e565b909155506113be90508484615843565b6102fd60008282546113d0919061588e565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b6000611032613954565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114615760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114aa600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146114d05760405162461bcd60e51b8152600401610d159061594c565b6114d9816139ca565b604080516000808252602082019092526114f5918391906139d2565b50565b600033610cc981858561150b838361322e565b6115159190615843565b613360565b610292602052816000526040600020818154811061153757600080fd5b6000918252602090912001546001600160a01b03169150829050565b61155b613839565b3361156581613881565b156115825760405162461bcd60e51b8152600401610d1590615998565b61158b33611c7d565b8211156115c05760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546115d59190615843565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165b91906159b4565b1015801561166c57506102fe548411155b905081806116775750805b6116a95760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116b63387612f34565b91509150806102fc60008282546116cd9190615843565b92505081905550816102fe60008282546116e7919061588e565b9091555060019050336001600160a01b0316600019600080516020615e758339815191528986600260405161171e939291906159cd565b60405180910390a46117303382613b3d565b61173a3383613c84565b50505050505050565b61174b613839565b3361175581613881565b156117725760405162461bcd60e51b8152600401610d1590615998565b60006102ff838154811061178857611788615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118045760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd6000828254611824919061588e565b90915550506102ff80548490811061183e5761183e615856565b6000918252602082200155600181600001516001600160a01b031684600080516020615e75833981519152846020015185602001516001604051611884939291906159e8565b60405180910390a46118a7816000015182602001516001600160601b0316613cb1565b505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118f45760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661193d600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146119635760405162461bcd60e51b8152600401610d159061594c565b61196c826139ca565b611978828260016139d2565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a1c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615e5583398151915290565b6103018181548110611a4057600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613d86565b611a7d613484565b610302546000199060005b81811015611ae257836001600160a01b03166103028281548110611aae57611aae615856565b6000918252602090912001546001600160a01b031603611ad057809250611ae2565b80611ada816158e7565b915050611a88565b506000198213611b1a5760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b2860018361588e565b81548110611b3857611b38615856565b60009182526020909120015461030280546001600160a01b039092169184908110611b6557611b65615856565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611ba557611ba5615a0d565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611bd4613484565b60405163433e3bad60e11b8152610290600482015261ffff82166024820152733F0Ff9947550d7Cf26549136552C785446ad4Ac59063867c775a9060440160006040518083038186803b158015611c2a57600080fd5b505af4158015611c3e573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611c88826130d9565b611c9183612527565b610ccf9190615843565b611ca3613484565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d1b5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d23613839565b60006102ff8281548110611d3957611d39615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611daa5760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611db590613881565b15611de85760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611df26131a7565b611dfc919061586c565b81602001516001600160601b031611611e3d5760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611e5b836000015184602001516001600160601b0316612f34565b915091506000611e746102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee291906159b4565b9050806102fe54611ef39190615843565b831115611f285760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f3b9190615843565b9250508190555083602001516001600160601b03166102fd6000828254611f62919061588e565b9091555050610300548503611f88576103008054906000611f82836158e7565b91905055505b600184600001516001600160a01b031686600080516020615e758339815191528760200151876002604051611fbf939291906158c3565b60405180910390a46102ff8581548110611fdb57611fdb615856565b600091825260208220015580831161201d57612018338551856120076102c6546001600160a01b031690565b6001600160a01b0316929190613df5565b61207a565b6000612029828561588e565b9050806102fe600082825461203e919061588e565b9091555061205e9050338651846120076102c6546001600160a01b031690565b8451612078908261135b6102c6546001600160a01b031690565b505b612082613e2d565b5050505050565b6102fb546001600160a01b0316336001600160a01b0316146120d35760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6120db613839565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015612132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215691906159b4565b81111561218b5760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe5461219c9190615843565b90506121a66131a7565b8111156121db5760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546121ee9190615843565b9091555061197890503330846120076102c6546001600160a01b031690565b612215613484565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122685760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119788282613e96565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a23565b6122e9613839565b816122f381613881565b156123105760405162461bcd60e51b8152600401610d1590615998565b8161231a81613881565b156123375760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038481166000908152610291602052604090205416156123865760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b0384166123c25760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166123fe5760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124455760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b61244d612272565b6001600160a01b0316336001600160a01b031614806124745750336001600160a01b038516145b6124a65760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124b1846001613f88565b6124bc836001613f88565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c3890615729565b6001600160a01b038116600090815260976020526040812054610ccf565b61254d613484565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125a8613839565b336125b281613881565b156125cf5760405162461bcd60e51b8152600401610d1590615998565b6125d833611c7d565b82111561260d5760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b0382111561264a5760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660e35fa931a0000146126865760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b6000604051806040016040528061269a3390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906159b4565b101580156127475750600061030054115b156127b557610300805490600061275d83615a40565b9190505550610300549050816102ff828154811061277d5761277d615856565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561281f565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec90920191909155905461281c919061588e565b90505b836102fd60008282546128329190615843565b9091555060019050336001600160a01b031682600080516020615e7583398151915287886000604051612867939291906159cd565b60405180910390a46128793385613b3d565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d80600081146128c7576040519150601f19603f3d011682016040523d82523d6000602084013e6128cc565b606091505b50509050806120825760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b60003381612911828661322e565b9050838110156129715760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b61297e8286868403613360565b506001949350505050565b612991613484565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b6129bc613839565b816129c681613881565b156129e35760405162461bcd60e51b8152600401610d1590615998565b816129ed81613881565b15612a0a5760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038416612a465760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612a825760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612a8a612272565b6001600160a01b0316336001600160a01b03161480612ab15750336001600160a01b038516145b612ae35760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b365760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b41846001613f88565b612b4c836001613f88565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612bd7576001600160a01b0385811660009081526102926020526040902080549188169183908110612ba357612ba3615856565b6000918252602090912001546001600160a01b031603612bc557809150612bd7565b80612bcf816158e7565b915050612b52565b506000811215612be957612be9615a57565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c2d9060019061588e565b81548110612c3d57612c3d615856565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612c7b57612c7b615856565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612cc157612cc1615a0d565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561367d565b612d00613484565b60006102fe54612d196102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8391906159b4565b612d8d919061588e565b905060008111612dc55760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b6114f5612ddb6102c6546001600160a01b031690565b82613e96565b612de9613839565b33612df381613881565b15612e105760405162461bcd60e51b8152600401610d1590615998565b81612e246102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9b91906159b4565b1015612ecf5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612ee29190615843565b9091555060009050336001600160a01b0316600019600080516020615e7583398151915285866002604051612f19939291906159cd565b60405180910390a4612f2b338361405d565b50611978613e2d565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fab91906159b4565b10612fbb57508190506000613049565b6000612fd8612fd361028e546001600160a01b031690565b6140de565b90506000612fe6858361414b565b6102fb5490915060009061300790600160a01b900463ffffffff1684614189565b905060006130166064856141b5565b6130208385615a6d565b61302a919061586c565b905061303681856141e3565b9450613042858861588e565b9550505050505b9250929050565b6102ff8181548110611a4057600080fd5b60405163106d64cf60e31b81526102906004820152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063836b267890602401602060405180830381865af41580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a84565b6000610ccf82600161421a565b6130ee613484565b60006102fc54116131275760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131635760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe6000828254613179919061588e565b90915550506102fc805460009091556114f5613193612272565b8261135b6102c6546001600160a01b031690565b6000806131c0612fd361028e546001600160a01b031690565b905060006131d56131cf61100c565b8361414b565b6102fb549091506000906131f690600160c01b900463ffffffff1684614189565b905060006132056064856141b5565b61320f8385615a6d565b613219919061586c565b905061322581856141e3565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b613261613484565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061329957600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6132c6613484565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b6132fb613484565b61271063ffffffff821611156133395760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166133c25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134235760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361348d612272565b6001600160a01b0316146134e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661350c5760405162461bcd60e51b8152600401610d1590615aa1565b613517858585614780565b61352182826147da565b61208261480b565b600054610100900460ff166135505760405162461bcd60e51b8152600401610d1590615aa1565b6114f581614832565b600054610100900460ff166135805760405162461bcd60e51b8152600401610d1590615aa1565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b8152610290600482015260006024820152733F0Ff9947550d7Cf26549136552C785446ad4Ac59063867c775a9060440160006040518083038186803b1580156135ef57600080fd5b505af4158015612082573d6000803e3d6000fd5b600061360f848461322e565b90506000198114613677578181101561366a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136778484848403613360565b50505050565b6001600160a01b0383166136e15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137435760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b61374e8383836148d4565b6001600160a01b038316600090815260976020526040902054818110156137c65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138269086815260200190565b60405180910390a3613677848484614913565b613841611a6b565b156134e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615aec565b6040516001600160a01b0383166024820152604481018290526118a790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a1c565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa9250505080156139bb575060408051601f3d908101601f191682019092526139b891810190615b0e565b60015b6139c55750601290565b919050565b6114f5613484565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a05576118a783614af1565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613a5f575060408051601f3d908101601f19168201909252613a5c918101906159b4565b60015b613ac25760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615e558339815191528114613b315760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118a7838383614b8d565b6001600160a01b038216613b9d5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613ba9826000836148d4565b6001600160a01b03821660009081526097602052604090205481811015613c1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118a783600084614913565b6000613c903383613b3d565b6102c654613ca8906001600160a01b031684846138f1565b50600192915050565b6001600160a01b038216613d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d13600083836148d4565b8060996000828254613d259190615843565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361197860008383614913565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613dd1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615aec565b6040516001600160a01b03808516602483015283166044820152606481018290526136779085906323b872dd60e01b9060840161391d565b6000613e376131a7565b9050806102fe5411613e465750565b6000816102fe54613e57919061588e565b9050806102fe6000828254613e6c919061588e565b90915550506102fb54611978906001600160a01b03168261135b6102c6546001600160a01b031690565b613e9e613484565b60008111613ed45760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4091906159b4565b1015613f745760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118a76001600160a01b03821633846138f1565b6102935460ff1615613f98575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603613fc6575050565b6001600160a01b0380831660009081526102916020526040902054168015613ff2576118a78183613f88565b6000613ffe848461421a565b9050801561405457610293805460ff1916600117905560006140208583614bb2565b610293805460ff19169055905080614052576001600160a01b038516600090815261028f602052604090206003018290555b505b61367784614c09565b6000333081036140bb5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c6546140d4906001600160a01b0316823086613df5565b610cc98484613cb1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561411e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141429190615b0e565b60ff1692915050565b6000600382101561417d5761416182600661588e565b61416c90600a615c15565b6141769084615a6d565b9050610ccf565b611087836103e8615a6d565b600060038210156141a057614176836103e8615a6d565b6141ab82600a615c15565b6110879084615a6d565b600060038210156141cd5761417683620f4240615a6d565b6141d8826003615843565b6141ab90600a615c15565b6000600382101561420e576141f982600661588e565b61420490600a615c15565b614176908461586c565b6110876103e88461586c565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161428b85614d6b565b82515190915064ffffffffff1615806142a2575080155b156142b257600092505050610ccf565b815160200151604051630b27cfb160e31b8152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906142f690610290908690600401615c21565b6040805180830381865af4158015614312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143369190615c45565b60405163038255fd60e11b81526102906004820152909150600090733F0Ff9947550d7Cf26549136552C785446ad4Ac590630704abfa906024016040805180830381865af415801561438c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b09190615c90565b905084602001519550733F0Ff9947550d7Cf26549136552C785446ad4Ac5634ead0c5384836040518363ffffffff1660e01b81526004016143f2929190615cbc565b602060405180830381865af415801561440f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144339190615aec565b61474457604051633e1e5c5360e11b8152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac590637c3cb8a690614471908790600401615cf0565b6040805180830381865af415801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615c90565b604051630b27cfb160e31b8152909150600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906144f290610290908690600401615c21565b6040805180830381865af415801561450e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145329190615c45565b87515160208201518651929350614560928c61454f576000614551565b8b5b61455b908b615843565b614e14565b61456a9089615843565b97505b819450809350733F0Ff9947550d7Cf26549136552C785446ad4Ac5634ead0c5386856040518363ffffffff1660e01b81526004016145ac929190615cbc565b602060405180830381865af41580156145c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ed9190615aec565b61471757604051633e1e5c5360e11b8152733F0Ff9947550d7Cf26549136552C785446ad4Ac590637c3cb8a690614628908890600401615cf0565b6040805180830381865af4158015614644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146689190615c90565b604051630b27cfb160e31b8152909250733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906146a690610290908690600401615c21565b6040805180830381865af41580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e69190615c45565b90506147068460200151826020015186600001518c61454f576000614551565b6147109089615843565b975061456d565b61473184602001514286600001518c61454f576000614551565b61473b9089615843565b97505050614775565b8451518251614768919042908a61475c57600061475e565b895b61455b9089615843565b6147729087615843565b95505b505050505092915050565b600054610100900460ff166147a75760405162461bcd60e51b8152600401610d1590615aa1565b6147af61480b565b6147b883614f00565b6147c0614f30565b6147c982614f5f565b6147d281614fa9565b6118a761480b565b600054610100900460ff166148015760405162461bcd60e51b8152600401610d1590615aa1565b6119788282614ff3565b600054610100900460ff166134e35760405162461bcd60e51b8152600401610d1590615aa1565b600054610100900460ff166148595760405162461bcd60e51b8152600401610d1590615aa1565b306001600160a01b038216036148b15760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6148df838383615033565b6001600160a01b038316156148f9576148f9836001613f88565b6001600160a01b038216156118a7576118a7826001613f88565b6001600160a01b038316158061493057506001600160a01b038216155b15614970577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f61495e61100c565b60405190815260200160405180910390a15b60005b6103025481101561367757610302818154811061499257614992615856565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b1580156149f157600080fd5b505af1158015614a05573d6000803e3d6000fd5b505050508080614a14906158e7565b915050614973565b6000614a71826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150949092919063ffffffff16565b9050805160001480614a92575080806020019051810190614a929190615aec565b6118a75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614b5e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615e5583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614b96836150a3565b600082511180614ba35750805b156118a75761367783836150e3565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614be885612527565b60408051918252602082018690520160405180910390a2613ca88383613cb1565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b81526102906004820152733F0Ff9947550d7Cf26549136552C785446ad4Ac590630704abfa906024016040805180830381865af4158015614c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cab9190615c90565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b03821660009081526102926020526040902054811015611978576001600160a01b0382166000908152610292602052604090208054614d59919083908110614d3f57614d3f615856565b6000918252602090912001546001600160a01b0316614c09565b80614d63816158e7565b915050614cee565b6000614d7682615108565b614d809082615843565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e0e576001600160a01b0383166000908152610292602052604090208054614df0919083908110614dd657614dd6615856565b6000918252602090912001546001600160a01b0316614d6b565b614dfa9083615843565b915080614e06816158e7565b915050614d85565b50919050565b600080614e2d612fd361028e546001600160a01b031690565b90506000614e4b614e3e8888615d0d565b64ffffffffff16836141b5565b90506000614e5d6301e13380846141b5565b614e686001856141b5565b614e729084615a6d565b614e7c919061586c565b90506000614e8e8761ffff1685614189565b90506000614e9d6001866141b5565b614ea78385615a6d565b614eb1919061586c565b90506000614ebf888761414b565b90506000614ece6064886141b5565b614ed88484615a6d565b614ee2919061586c565b9050614eee81886141e3565b9750505050505050505b949350505050565b600054610100900460ff16614f275760405162461bcd60e51b8152600401610d1590615aa1565b6114f581615113565b600054610100900460ff16614f575760405162461bcd60e51b8152600401610d1590615aa1565b6134e361515d565b600054610100900460ff16614f865760405162461bcd60e51b8152600401610d1590615aa1565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16614fd05760405162461bcd60e51b8152600401610d1590615aa1565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661501a5760405162461bcd60e51b8152600401610d1590615aa1565b609a6150268382615d78565b50609b6118a78282615d78565b61503b613839565b8261504581613881565b156150625760405162461bcd60e51b8152600401610d1590615998565b8261506c81613881565b156150895760405162461bcd60e51b8152600401610d1590615998565b612082858585615190565b6060614ef884846000856151f8565b6150ac81614af1565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615e95602791396152d3565b6000610ccf82612527565b600054610100900460ff1661513a5760405162461bcd60e51b8152600401610d1590615aa1565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151845760405162461bcd60e51b8152600401610d1590615aa1565b60c9805460ff19169055565b615198611a6b565b156118a75760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152759190615e38565b60006040518083038185875af1925050503d80600081146152b2576040519150601f19603f3d011682016040523d82523d6000602084013e6152b7565b606091505b50915091506152c88783838761534b565b979650505050505050565b6060600080856001600160a01b0316856040516152f09190615e38565b600060405180830381855af49150503d806000811461532b576040519150601f19603f3d011682016040523d82523d6000602084013e615330565b606091505b50915091506153418683838761534b565b9695505050505050565b606083156153ba5782516000036153b3576001600160a01b0385163b6153b35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614ef8565b614ef883838151156153cf5781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061540d565b60005b838110156154045781810151838201526020016153ec565b50506000910152565b602081526000825180602084015261542c8160408501602087016153e9565b601f01601f19169190910160400192915050565b6001600160a01b03811681146114f557600080fd5b6000806040838503121561546857600080fd5b823561547381615440565b946020939093013593505050565b60006020828403121561549357600080fd5b813561108781615440565b600080600080600060a086880312156154b657600080fd5b85356154c181615440565b945060208601356154d181615440565b935060408601356154e181615440565b925060608601356154f181615440565b9150608086013561550181615440565b809150509295509295909350565b60008060006060848603121561552457600080fd5b833561552f81615440565b9250602084013561553f81615440565b929592945050506040919091013590565b60006020828403121561556257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155a2576155a2615569565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156155d1576155d1615569565b604052919050565b600067ffffffffffffffff8211156155f3576155f3615569565b50601f01601f191660200190565b6000806040838503121561561457600080fd5b823561561f81615440565b9150602083013567ffffffffffffffff81111561563b57600080fd5b8301601f8101851361564c57600080fd5b803561565f61565a826155d9565b6155a8565b81815286602083850101111561567457600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff811681146114f557600080fd5b6000602082840312156156b657600080fd5b813561108781615694565b600080604083850312156156d457600080fd5b82356156df81615440565b915060208301356156ef81615440565b809150509250929050565b63ffffffff811681146114f557600080fd5b60006020828403121561571e57600080fd5b8135611087816156fa565b600181811c9082168061573d57607f821691505b602082108103614e0e57634e487b7160e01b600052602260045260246000fd5b60006020828403121561576f57600080fd5b815167ffffffffffffffff81111561578657600080fd5b8201601f8101841361579757600080fd5b80516157a561565a826155d9565b8181528560208385010111156157ba57600080fd5b6157cb8260208301602086016153e9565b95945050505050565b6702632b233b4ba3c960c51b8152600082516157f78160088501602087016153e9565b9190910160080192915050565b601360fa1b8152600082516158208160018501602087016153e9565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf61582d565b634e487b7160e01b600052603260045260246000fd5b60008261588957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ccf57610ccf61582d565b600381106158bf57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03841681526020810183905260608101614ef860408301846158a1565b6000600182016158f9576158f961582d565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b6000602082840312156159c657600080fd5b5051919050565b8381526020810183905260608101614ef860408301846158a1565b6001600160601b0384811682528316602082015260608101614ef860408301846158a1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a3557600080fd5b815161108781615440565b600081615a4f57615a4f61582d565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf61582d565b600060208284031215615a9657600080fd5b815161108781615694565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615afe57600080fd5b8151801515811461108757600080fd5b600060208284031215615b2057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615b6c578160001904821115615b5257615b5261582d565b80851615615b5f57918102915b93841c9390800290615b36565b509250929050565b600082615b8357506001610ccf565b81615b9057506000610ccf565b8160018114615ba65760028114615bb057615bcc565b6001915050610ccf565b60ff841115615bc157615bc161582d565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615bef575081810a610ccf565b615bf98383615b31565b8060001904821115615c0d57615c0d61582d565b029392505050565b60006110878383615b74565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615c5757600080fd5b615c5f61557f565b8251615c6a81615694565b8152602083015164ffffffffff81168114615c8457600080fd5b60208201529392505050565b600060408284031215615ca257600080fd5b615caa61557f565b825181526020830151615c84816156fa565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d2b57615d2b61582d565b5092915050565b601f8211156118a757600081815260208120601f850160051c81016020861015615d595750805b601f850160051c820191505b8181101561100457828155600101615d65565b815167ffffffffffffffff811115615d9257615d92615569565b615da681615da08454615729565b84615d32565b602080601f831160018114615ddb5760008415615dc35750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e0a57888601518255948401946001909101908401615deb565b5085821015615e285787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615e4a8184602087016153e9565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcfeb6a900a360475a17ff2a61d90610bd38f52b2b474c52828b8411221ff2576f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e1d4dd61867ca96be7efe83d7ca66dcd56b3ec13ae334b24d813c7fd7fe3c42d64736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061540d565b60405180910390f35b34801561041557600080fd5b50610429610424366004615455565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615481565b610cd5565b005b34801561046757600080fd5b50610459610476366004615481565b610d41565b34801561048757600080fd5b5061045961049636600461549e565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f0366004615455565b611037565b34801561050157600080fd5b5061042961051036600461550f565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b50610429610545366004615455565b6113de565b34801561055657600080fd5b5061055f61140f565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615481565b611419565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e5366004615455565b6114f8565b3480156105f657600080fd5b506105b2610605366004615455565b61151a565b34801561061657600080fd5b50610459610625366004615550565b611553565b34801561063657600080fd5b50610459610645366004615550565b611743565b610459610658366004615601565b6118ac565b34801561066957600080fd5b506104b061197c565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a4366004615550565b611a2f565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611a6b565b3480156106f157600080fd5b50610459610700366004615481565b611a75565b34801561071157600080fd5b506104596107203660046156a4565b611bcc565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615481565b611c7d565b34801561077057600080fd5b50610459611c9b565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c2366004615550565b611cd1565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b50610459610801366004615550565b612089565b34801561081257600080fd5b50610459610821366004615455565b61220d565b34801561083257600080fd5b506105b2610841366004615481565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b2612272565b34801561087e57600080fd5b5061045961088d3660046156c1565b6122e1565b34801561089e57600080fd5b506103f3612518565b3480156108b357600080fd5b506104b06108c2366004615481565b612527565b3480156108d357600080fd5b506104596108e2366004615481565b612545565b6104596108f5366004615550565b6125a0565b34801561090657600080fd5b50610429610915366004615455565b612903565b34801561092657600080fd5b50610459610935366004615481565b612989565b34801561094657600080fd5b506104596109553660046156c1565b6129b4565b34801561096657600080fd5b50610429610975366004615455565b612cea565b34801561098657600080fd5b50610459612cf8565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb366004615550565b612de1565b3480156109dc57600080fd5b506109f06109eb366004615455565b612f34565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a20366004615550565b613050565b348015610a3157600080fd5b50610a3a613061565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615481565b6130d9565b348015610af357600080fd5b506104596130e6565b348015610b0857600080fd5b506104b06131a7565b348015610b1d57600080fd5b506104b0610b2c3660046156c1565b61322e565b348015610b3d57600080fd5b50610459610b4c36600461570c565b613259565b348015610b5d57600080fd5b506105b2610b6c366004615550565b613288565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b06132b3565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615481565b6132be565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461570c565b6132f3565b6060609a8054610c3890615729565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6490615729565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc9818585613360565b60019150505b92915050565b610cdd613484565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613484565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed0919081019061575d565b9050610f1d87878784604051602001610ee991906157d4565b60405160208183030381529060405285604051602001610f099190615804565b6040516020818303038152906040526134e5565b610f2683613529565b610f2f30613559565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f73612272565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c612272565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e6132b3565b6110289190615843565b6110329190615843565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613603565b61108185858561367d565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e0613839565b610300546102ff5460009182915b808210156113815761afc85a106113815760006102ff838154811061111557611115615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925291501561136e57805161116490613881565b156111e6576102ff838154811061117d5761117d615856565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa49091015561136e565b60026111f06131a7565b6111fa919061586c565b81602001516001600160601b0316111561128b576102ff838154811061122257611222615856565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9091015561136e565b6000806112a9836000015184602001516001600160601b0316612f34565b91509150856102fe546112bc919061588e565b8211156112cb57505050611381565b6112d58188615843565b96506112e18287615843565b9550600183600001516001600160a01b031686600080516020615e75833981519152866020015186600260405161131a939291906158c3565b60405180910390a46102ff858154811061133657611336615856565b6000918252602082200155825161136b908361135b6102c6546001600160a01b031690565b6001600160a01b031691906138f1565b50505b82611378816158e7565b935050506110ee565b836102fc60008282546113949190615843565b92505081905550826102fe60008282546113ae919061588e565b909155506113be90508484615843565b6102fd60008282546113d0919061588e565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b6000611032613954565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114615760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114aa600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146114d05760405162461bcd60e51b8152600401610d159061594c565b6114d9816139ca565b604080516000808252602082019092526114f5918391906139d2565b50565b600033610cc981858561150b838361322e565b6115159190615843565b613360565b610292602052816000526040600020818154811061153757600080fd5b6000918252602090912001546001600160a01b03169150829050565b61155b613839565b3361156581613881565b156115825760405162461bcd60e51b8152600401610d1590615998565b61158b33611c7d565b8211156115c05760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546115d59190615843565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165b91906159b4565b1015801561166c57506102fe548411155b905081806116775750805b6116a95760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116b63387612f34565b91509150806102fc60008282546116cd9190615843565b92505081905550816102fe60008282546116e7919061588e565b9091555060019050336001600160a01b0316600019600080516020615e758339815191528986600260405161171e939291906159cd565b60405180910390a46117303382613b3d565b61173a3383613c84565b50505050505050565b61174b613839565b3361175581613881565b156117725760405162461bcd60e51b8152600401610d1590615998565b60006102ff838154811061178857611788615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118045760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd6000828254611824919061588e565b90915550506102ff80548490811061183e5761183e615856565b6000918252602082200155600181600001516001600160a01b031684600080516020615e75833981519152846020015185602001516001604051611884939291906159e8565b60405180910390a46118a7816000015182602001516001600160601b0316613cb1565b505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118f45760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661193d600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146119635760405162461bcd60e51b8152600401610d159061594c565b61196c826139ca565b611978828260016139d2565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a1c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615e5583398151915290565b6103018181548110611a4057600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613d86565b611a7d613484565b610302546000199060005b81811015611ae257836001600160a01b03166103028281548110611aae57611aae615856565b6000918252602090912001546001600160a01b031603611ad057809250611ae2565b80611ada816158e7565b915050611a88565b506000198213611b1a5760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b2860018361588e565b81548110611b3857611b38615856565b60009182526020909120015461030280546001600160a01b039092169184908110611b6557611b65615856565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611ba557611ba5615a0d565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611bd4613484565b60405163433e3bad60e11b8152610290600482015261ffff8216602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b158015611c2a57600080fd5b505af4158015611c3e573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611c88826130d9565b611c9183612527565b610ccf9190615843565b611ca3613484565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d1b5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d23613839565b60006102ff8281548110611d3957611d39615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611daa5760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611db590613881565b15611de85760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611df26131a7565b611dfc919061586c565b81602001516001600160601b031611611e3d5760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611e5b836000015184602001516001600160601b0316612f34565b915091506000611e746102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee291906159b4565b9050806102fe54611ef39190615843565b831115611f285760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f3b9190615843565b9250508190555083602001516001600160601b03166102fd6000828254611f62919061588e565b9091555050610300548503611f88576103008054906000611f82836158e7565b91905055505b600184600001516001600160a01b031686600080516020615e758339815191528760200151876002604051611fbf939291906158c3565b60405180910390a46102ff8581548110611fdb57611fdb615856565b600091825260208220015580831161201d57612018338551856120076102c6546001600160a01b031690565b6001600160a01b0316929190613df5565b61207a565b6000612029828561588e565b9050806102fe600082825461203e919061588e565b9091555061205e9050338651846120076102c6546001600160a01b031690565b8451612078908261135b6102c6546001600160a01b031690565b505b612082613e2d565b5050505050565b6102fb546001600160a01b0316336001600160a01b0316146120d35760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6120db613839565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015612132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215691906159b4565b81111561218b5760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe5461219c9190615843565b90506121a66131a7565b8111156121db5760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546121ee9190615843565b9091555061197890503330846120076102c6546001600160a01b031690565b612215613484565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122685760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119788282613e96565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a23565b6122e9613839565b816122f381613881565b156123105760405162461bcd60e51b8152600401610d1590615998565b8161231a81613881565b156123375760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038481166000908152610291602052604090205416156123865760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b0384166123c25760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166123fe5760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124455760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b61244d612272565b6001600160a01b0316336001600160a01b031614806124745750336001600160a01b038516145b6124a65760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124b1846001613f88565b6124bc836001613f88565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c3890615729565b6001600160a01b038116600090815260976020526040812054610ccf565b61254d613484565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125a8613839565b336125b281613881565b156125cf5760405162461bcd60e51b8152600401610d1590615998565b6125d833611c7d565b82111561260d5760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b0382111561264a5760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660e35fa931a0000146126865760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b6000604051806040016040528061269a3390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906159b4565b101580156127475750600061030054115b156127b557610300805490600061275d83615a40565b9190505550610300549050816102ff828154811061277d5761277d615856565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561281f565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec90920191909155905461281c919061588e565b90505b836102fd60008282546128329190615843565b9091555060019050336001600160a01b031682600080516020615e7583398151915287886000604051612867939291906159cd565b60405180910390a46128793385613b3d565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d80600081146128c7576040519150601f19603f3d011682016040523d82523d6000602084013e6128cc565b606091505b50509050806120825760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b60003381612911828661322e565b9050838110156129715760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b61297e8286868403613360565b506001949350505050565b612991613484565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b6129bc613839565b816129c681613881565b156129e35760405162461bcd60e51b8152600401610d1590615998565b816129ed81613881565b15612a0a5760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038416612a465760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612a825760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612a8a612272565b6001600160a01b0316336001600160a01b03161480612ab15750336001600160a01b038516145b612ae35760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b365760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b41846001613f88565b612b4c836001613f88565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612bd7576001600160a01b0385811660009081526102926020526040902080549188169183908110612ba357612ba3615856565b6000918252602090912001546001600160a01b031603612bc557809150612bd7565b80612bcf816158e7565b915050612b52565b506000811215612be957612be9615a57565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c2d9060019061588e565b81548110612c3d57612c3d615856565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612c7b57612c7b615856565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612cc157612cc1615a0d565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561367d565b612d00613484565b60006102fe54612d196102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8391906159b4565b612d8d919061588e565b905060008111612dc55760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b6114f5612ddb6102c6546001600160a01b031690565b82613e96565b612de9613839565b33612df381613881565b15612e105760405162461bcd60e51b8152600401610d1590615998565b81612e246102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9b91906159b4565b1015612ecf5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612ee29190615843565b9091555060009050336001600160a01b0316600019600080516020615e7583398151915285866002604051612f19939291906159cd565b60405180910390a4612f2b338361405d565b50611978613e2d565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fab91906159b4565b10612fbb57508190506000613049565b6000612fd8612fd361028e546001600160a01b031690565b6140de565b90506000612fe6858361414b565b6102fb5490915060009061300790600160a01b900463ffffffff1684614189565b905060006130166064856141b5565b6130208385615a6d565b61302a919061586c565b905061303681856141e3565b9450613042858861588e565b9550505050505b9250929050565b6102ff8181548110611a4057600080fd5b60405163106d64cf60e31b8152610290600482015260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063836b267890602401602060405180830381865af41580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a84565b6000610ccf82600161421a565b6130ee613484565b60006102fc54116131275760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131635760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe6000828254613179919061588e565b90915550506102fc805460009091556114f5613193612272565b8261135b6102c6546001600160a01b031690565b6000806131c0612fd361028e546001600160a01b031690565b905060006131d56131cf61100c565b8361414b565b6102fb549091506000906131f690600160c01b900463ffffffff1684614189565b905060006132056064856141b5565b61320f8385615a6d565b613219919061586c565b905061322581856141e3565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b613261613484565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061329957600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6132c6613484565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b6132fb613484565b61271063ffffffff821611156133395760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166133c25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134235760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361348d612272565b6001600160a01b0316146134e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661350c5760405162461bcd60e51b8152600401610d1590615aa1565b613517858585614780565b61352182826147da565b61208261480b565b600054610100900460ff166135505760405162461bcd60e51b8152600401610d1590615aa1565b6114f581614832565b600054610100900460ff166135805760405162461bcd60e51b8152600401610d1590615aa1565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b815261029060048201526000602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b1580156135ef57600080fd5b505af4158015612082573d6000803e3d6000fd5b600061360f848461322e565b90506000198114613677578181101561366a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136778484848403613360565b50505050565b6001600160a01b0383166136e15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137435760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b61374e8383836148d4565b6001600160a01b038316600090815260976020526040902054818110156137c65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138269086815260200190565b60405180910390a3613677848484614913565b613841611a6b565b156134e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615aec565b6040516001600160a01b0383166024820152604481018290526118a790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a1c565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa9250505080156139bb575060408051601f3d908101601f191682019092526139b891810190615b0e565b60015b6139c55750601290565b919050565b6114f5613484565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a05576118a783614af1565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613a5f575060408051601f3d908101601f19168201909252613a5c918101906159b4565b60015b613ac25760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615e558339815191528114613b315760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118a7838383614b8d565b6001600160a01b038216613b9d5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613ba9826000836148d4565b6001600160a01b03821660009081526097602052604090205481811015613c1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118a783600084614913565b6000613c903383613b3d565b6102c654613ca8906001600160a01b031684846138f1565b50600192915050565b6001600160a01b038216613d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d13600083836148d4565b8060996000828254613d259190615843565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361197860008383614913565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613dd1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615aec565b6040516001600160a01b03808516602483015283166044820152606481018290526136779085906323b872dd60e01b9060840161391d565b6000613e376131a7565b9050806102fe5411613e465750565b6000816102fe54613e57919061588e565b9050806102fe6000828254613e6c919061588e565b90915550506102fb54611978906001600160a01b03168261135b6102c6546001600160a01b031690565b613e9e613484565b60008111613ed45760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4091906159b4565b1015613f745760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118a76001600160a01b03821633846138f1565b6102935460ff1615613f98575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603613fc6575050565b6001600160a01b0380831660009081526102916020526040902054168015613ff2576118a78183613f88565b6000613ffe848461421a565b9050801561405457610293805460ff1916600117905560006140208583614bb2565b610293805460ff19169055905080614052576001600160a01b038516600090815261028f602052604090206003018290555b505b61367784614c09565b6000333081036140bb5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c6546140d4906001600160a01b0316823086613df5565b610cc98484613cb1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561411e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141429190615b0e565b60ff1692915050565b6000600382101561417d5761416182600661588e565b61416c90600a615c15565b6141769084615a6d565b9050610ccf565b611087836103e8615a6d565b600060038210156141a057614176836103e8615a6d565b6141ab82600a615c15565b6110879084615a6d565b600060038210156141cd5761417683620f4240615a6d565b6141d8826003615843565b6141ab90600a615c15565b6000600382101561420e576141f982600661588e565b61420490600a615c15565b614176908461586c565b6110876103e88461586c565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161428b85614d6b565b82515190915064ffffffffff1615806142a2575080155b156142b257600092505050610ccf565b815160200151604051630b27cfb160e31b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906142f690610290908690600401615c21565b6040805180830381865af4158015614312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143369190615c45565b60405163038255fd60e11b8152610290600482015290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af415801561438c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b09190615c90565b90508460200151955073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5384836040518363ffffffff1660e01b81526004016143f2929190615cbc565b602060405180830381865af415801561440f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144339190615aec565b61474457604051633e1e5c5360e11b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a690614471908790600401615cf0565b6040805180830381865af415801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615c90565b604051630b27cfb160e31b815290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906144f290610290908690600401615c21565b6040805180830381865af415801561450e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145329190615c45565b87515160208201518651929350614560928c61454f576000614551565b8b5b61455b908b615843565b614e14565b61456a9089615843565b97505b81945080935073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5386856040518363ffffffff1660e01b81526004016145ac929190615cbc565b602060405180830381865af41580156145c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ed9190615aec565b61471757604051633e1e5c5360e11b815273__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a690614628908890600401615cf0565b6040805180830381865af4158015614644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146689190615c90565b604051630b27cfb160e31b815290925073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906146a690610290908690600401615c21565b6040805180830381865af41580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e69190615c45565b90506147068460200151826020015186600001518c61454f576000614551565b6147109089615843565b975061456d565b61473184602001514286600001518c61454f576000614551565b61473b9089615843565b97505050614775565b8451518251614768919042908a61475c57600061475e565b895b61455b9089615843565b6147729087615843565b95505b505050505092915050565b600054610100900460ff166147a75760405162461bcd60e51b8152600401610d1590615aa1565b6147af61480b565b6147b883614f00565b6147c0614f30565b6147c982614f5f565b6147d281614fa9565b6118a761480b565b600054610100900460ff166148015760405162461bcd60e51b8152600401610d1590615aa1565b6119788282614ff3565b600054610100900460ff166134e35760405162461bcd60e51b8152600401610d1590615aa1565b600054610100900460ff166148595760405162461bcd60e51b8152600401610d1590615aa1565b306001600160a01b038216036148b15760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6148df838383615033565b6001600160a01b038316156148f9576148f9836001613f88565b6001600160a01b038216156118a7576118a7826001613f88565b6001600160a01b038316158061493057506001600160a01b038216155b15614970577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f61495e61100c565b60405190815260200160405180910390a15b60005b6103025481101561367757610302818154811061499257614992615856565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b1580156149f157600080fd5b505af1158015614a05573d6000803e3d6000fd5b505050508080614a14906158e7565b915050614973565b6000614a71826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150949092919063ffffffff16565b9050805160001480614a92575080806020019051810190614a929190615aec565b6118a75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614b5e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615e5583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614b96836150a3565b600082511180614ba35750805b156118a75761367783836150e3565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614be885612527565b60408051918252602082018690520160405180910390a2613ca88383613cb1565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b8152610290600482015273__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af4158015614c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cab9190615c90565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b03821660009081526102926020526040902054811015611978576001600160a01b0382166000908152610292602052604090208054614d59919083908110614d3f57614d3f615856565b6000918252602090912001546001600160a01b0316614c09565b80614d63816158e7565b915050614cee565b6000614d7682615108565b614d809082615843565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e0e576001600160a01b0383166000908152610292602052604090208054614df0919083908110614dd657614dd6615856565b6000918252602090912001546001600160a01b0316614d6b565b614dfa9083615843565b915080614e06816158e7565b915050614d85565b50919050565b600080614e2d612fd361028e546001600160a01b031690565b90506000614e4b614e3e8888615d0d565b64ffffffffff16836141b5565b90506000614e5d6301e13380846141b5565b614e686001856141b5565b614e729084615a6d565b614e7c919061586c565b90506000614e8e8761ffff1685614189565b90506000614e9d6001866141b5565b614ea78385615a6d565b614eb1919061586c565b90506000614ebf888761414b565b90506000614ece6064886141b5565b614ed88484615a6d565b614ee2919061586c565b9050614eee81886141e3565b9750505050505050505b949350505050565b600054610100900460ff16614f275760405162461bcd60e51b8152600401610d1590615aa1565b6114f581615113565b600054610100900460ff16614f575760405162461bcd60e51b8152600401610d1590615aa1565b6134e361515d565b600054610100900460ff16614f865760405162461bcd60e51b8152600401610d1590615aa1565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16614fd05760405162461bcd60e51b8152600401610d1590615aa1565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661501a5760405162461bcd60e51b8152600401610d1590615aa1565b609a6150268382615d78565b50609b6118a78282615d78565b61503b613839565b8261504581613881565b156150625760405162461bcd60e51b8152600401610d1590615998565b8261506c81613881565b156150895760405162461bcd60e51b8152600401610d1590615998565b612082858585615190565b6060614ef884846000856151f8565b6150ac81614af1565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615e95602791396152d3565b6000610ccf82612527565b600054610100900460ff1661513a5760405162461bcd60e51b8152600401610d1590615aa1565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151845760405162461bcd60e51b8152600401610d1590615aa1565b60c9805460ff19169055565b615198611a6b565b156118a75760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152759190615e38565b60006040518083038185875af1925050503d80600081146152b2576040519150601f19603f3d011682016040523d82523d6000602084013e6152b7565b606091505b50915091506152c88783838761534b565b979650505050505050565b6060600080856001600160a01b0316856040516152f09190615e38565b600060405180830381855af49150503d806000811461532b576040519150601f19603f3d011682016040523d82523d6000602084013e615330565b606091505b50915091506153418683838761534b565b9695505050505050565b606083156153ba5782516000036153b3576001600160a01b0385163b6153b35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614ef8565b614ef883838151156153cf5781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061540d565b60005b838110156154045781810151838201526020016153ec565b50506000910152565b602081526000825180602084015261542c8160408501602087016153e9565b601f01601f19169190910160400192915050565b6001600160a01b03811681146114f557600080fd5b6000806040838503121561546857600080fd5b823561547381615440565b946020939093013593505050565b60006020828403121561549357600080fd5b813561108781615440565b600080600080600060a086880312156154b657600080fd5b85356154c181615440565b945060208601356154d181615440565b935060408601356154e181615440565b925060608601356154f181615440565b9150608086013561550181615440565b809150509295509295909350565b60008060006060848603121561552457600080fd5b833561552f81615440565b9250602084013561553f81615440565b929592945050506040919091013590565b60006020828403121561556257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155a2576155a2615569565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156155d1576155d1615569565b604052919050565b600067ffffffffffffffff8211156155f3576155f3615569565b50601f01601f191660200190565b6000806040838503121561561457600080fd5b823561561f81615440565b9150602083013567ffffffffffffffff81111561563b57600080fd5b8301601f8101851361564c57600080fd5b803561565f61565a826155d9565b6155a8565b81815286602083850101111561567457600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff811681146114f557600080fd5b6000602082840312156156b657600080fd5b813561108781615694565b600080604083850312156156d457600080fd5b82356156df81615440565b915060208301356156ef81615440565b809150509250929050565b63ffffffff811681146114f557600080fd5b60006020828403121561571e57600080fd5b8135611087816156fa565b600181811c9082168061573d57607f821691505b602082108103614e0e57634e487b7160e01b600052602260045260246000fd5b60006020828403121561576f57600080fd5b815167ffffffffffffffff81111561578657600080fd5b8201601f8101841361579757600080fd5b80516157a561565a826155d9565b8181528560208385010111156157ba57600080fd5b6157cb8260208301602086016153e9565b95945050505050565b6702632b233b4ba3c960c51b8152600082516157f78160088501602087016153e9565b9190910160080192915050565b601360fa1b8152600082516158208160018501602087016153e9565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf61582d565b634e487b7160e01b600052603260045260246000fd5b60008261588957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ccf57610ccf61582d565b600381106158bf57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03841681526020810183905260608101614ef860408301846158a1565b6000600182016158f9576158f961582d565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b6000602082840312156159c657600080fd5b5051919050565b8381526020810183905260608101614ef860408301846158a1565b6001600160601b0384811682528316602082015260608101614ef860408301846158a1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a3557600080fd5b815161108781615440565b600081615a4f57615a4f61582d565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf61582d565b600060208284031215615a9657600080fd5b815161108781615694565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615afe57600080fd5b8151801515811461108757600080fd5b600060208284031215615b2057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615b6c578160001904821115615b5257615b5261582d565b80851615615b5f57918102915b93841c9390800290615b36565b509250929050565b600082615b8357506001610ccf565b81615b9057506000610ccf565b8160018114615ba65760028114615bb057615bcc565b6001915050610ccf565b60ff841115615bc157615bc161582d565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615bef575081810a610ccf565b615bf98383615b31565b8060001904821115615c0d57615c0d61582d565b029392505050565b60006110878383615b74565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615c5757600080fd5b615c5f61557f565b8251615c6a81615694565b8152602083015164ffffffffff81168114615c8457600080fd5b60208201529392505050565b600060408284031215615ca257600080fd5b615caa61557f565b825181526020830151615c84816156fa565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d2b57615d2b61582d565b5092915050565b601f8211156118a757600081815260208120601f850160051c81016020861015615d595750805b601f850160051c820191505b8181101561100457828155600101615d65565b815167ffffffffffffffff811115615d9257615d92615569565b615da681615da08454615729565b84615d32565b602080601f831160018114615ddb5760008415615dc35750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e0a57888601518255948401946001909101908401615deb565b5085821015615e285787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615e4a8184602087016153e9565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcfeb6a900a360475a17ff2a61d90610bd38f52b2b474c52828b8411221ff2576f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e1d4dd61867ca96be7efe83d7ca66dcd56b3ec13ae334b24d813c7fd7fe3c42d64736f6c63430008120033", - "libraries": { - "APRHistory": "0x3F0Ff9947550d7Cf26549136552C785446ad4Ac5" - }, - "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)": { - "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.", - "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)": { - "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 - }, - "storageLayout": { - "storage": [ - { - "astId": 609, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 612, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 591, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 906, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "51", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 2785, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "101", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1053, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_balances", - "offset": 0, - "slot": "151", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 1059, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_allowances", - "offset": 0, - "slot": "152", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 1061, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_totalSupply", - "offset": 0, - "slot": "153", - "type": "t_uint256" - }, - { - "astId": 1063, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_name", - "offset": 0, - "slot": "154", - "type": "t_string_storage" - }, - { - "astId": 1065, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_symbol", - "offset": 0, - "slot": "155", - "type": "t_string_storage" - }, - { - "astId": 1645, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "156", - "type": "t_array(t_uint256)45_storage" - }, - { - "astId": 928, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_paused", - "offset": 0, - "slot": "201", - "type": "t_bool" - }, - { - "astId": 1033, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "202", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 116, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_owner", - "offset": 0, - "slot": "251", - "type": "t_address" - }, - { - "astId": 236, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "252", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 5727, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalOwner", - "offset": 0, - "slot": "301", - "type": "t_contract(GlobalOwner)3833" - }, - { - "astId": 5811, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "302", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5829, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalPause", - "offset": 0, - "slot": "352", - "type": "t_contract(GlobalPause)3909" - }, - { - "astId": 5888, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "353", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5902, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalBlacklist", - "offset": 0, - "slot": "403", - "type": "t_contract(GlobalBlacklist)3786" - }, - { - "astId": 5976, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "404", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 6995, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "454", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 7086, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "504", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1783, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "554", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 7191, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "604", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 6028, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_invested", - "offset": 0, - "slot": "654", - "type": "t_contract(IERC20Upgradeable)1724" - }, - { - "astId": 6034, - "contract": "contracts/src/LToken.sol:LToken", - "label": "accountsDetails", - "offset": 0, - "slot": "655", - "type": "t_mapping(t_address,t_struct(AccountDetails)6024_storage)" - }, - { - "astId": 6039, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_aprHistory", - "offset": 0, - "slot": "656", - "type": "t_array(t_struct(Pack)8859_storage)dyn_storage" - }, - { - "astId": 6044, - "contract": "contracts/src/LToken.sol:LToken", - "label": "rewardsRedirectsFromTo", - "offset": 0, - "slot": "657", - "type": "t_mapping(t_address,t_address)" - }, - { - "astId": 6049, - "contract": "contracts/src/LToken.sol:LToken", - "label": "rewardsRedirectsToFrom", - "offset": 0, - "slot": "658", - "type": "t_mapping(t_address,t_array(t_address)dyn_storage)" - }, - { - "astId": 6052, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_isClaiming", - "offset": 0, - "slot": "659", - "type": "t_bool" - }, - { - "astId": 6902, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "660", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1797, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_underlying", - "offset": 0, - "slot": "710", - "type": "t_contract(IERC20Upgradeable)1724" - }, - { - "astId": 1976, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "711", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 3968, - "contract": "contracts/src/LToken.sol:LToken", - "label": "ldyStaking", - "offset": 0, - "slot": "761", - "type": "t_contract(LDYStaking)3669" - }, - { - "astId": 3971, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawer", - "offset": 0, - "slot": "762", - "type": "t_address_payable" - }, - { - "astId": 3974, - "contract": "contracts/src/LToken.sol:LToken", - "label": "fund", - "offset": 0, - "slot": "763", - "type": "t_address" - }, - { - "astId": 3977, - "contract": "contracts/src/LToken.sol:LToken", - "label": "feesRateUD7x3", - "offset": 20, - "slot": "763", - "type": "t_uint32" - }, - { - "astId": 3980, - "contract": "contracts/src/LToken.sol:LToken", - "label": "retentionRateUD7x3", - "offset": 24, - "slot": "763", - "type": "t_uint32" - }, - { - "astId": 3983, - "contract": "contracts/src/LToken.sol:LToken", - "label": "unclaimedFees", - "offset": 0, - "slot": "764", - "type": "t_uint256" - }, - { - "astId": 3986, - "contract": "contracts/src/LToken.sol:LToken", - "label": "totalQueued", - "offset": 0, - "slot": "765", - "type": "t_uint256" - }, - { - "astId": 3989, - "contract": "contracts/src/LToken.sol:LToken", - "label": "usableUnderlyings", - "offset": 0, - "slot": "766", - "type": "t_uint256" - }, - { - "astId": 3994, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawalQueue", - "offset": 0, - "slot": "767", - "type": "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage" - }, - { - "astId": 3997, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawalQueueCursor", - "offset": 0, - "slot": "768", - "type": "t_uint256" - }, - { - "astId": 4002, - "contract": "contracts/src/LToken.sol:LToken", - "label": "frozenRequests", - "offset": 0, - "slot": "769", - "type": "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage" - }, - { - "astId": 4007, - "contract": "contracts/src/LToken.sol:LToken", - "label": "transfersListeners", - "offset": 0, - "slot": "770", - "type": "t_array(t_contract(ITransfersListener)8840)dyn_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_address_payable": { - "encoding": "inplace", - "label": "address payable", - "numberOfBytes": "20" - }, - "t_array(t_address)dyn_storage": { - "base": "t_address", - "encoding": "dynamic_array", - "label": "address[]", - "numberOfBytes": "32" - }, - "t_array(t_contract(ITransfersListener)8840)dyn_storage": { - "base": "t_contract(ITransfersListener)8840", - "encoding": "dynamic_array", - "label": "contract ITransfersListener[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(Pack)8859_storage)dyn_storage": { - "base": "t_struct(Pack)8859_storage", - "encoding": "dynamic_array", - "label": "struct APRHistory.Pack[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage": { - "base": "t_struct(WithdrawalRequest)3951_storage", - "encoding": "dynamic_array", - "label": "struct LToken.WithdrawalRequest[]", - "numberOfBytes": "32" - }, - "t_array(t_uint16)4_storage": { - "base": "t_uint16", - "encoding": "inplace", - "label": "uint16[4]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)45_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[45]", - "numberOfBytes": "1440" - }, - "t_array(t_uint256)49_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint40)4_storage": { - "base": "t_uint40", - "encoding": "inplace", - "label": "uint40[4]", - "numberOfBytes": "32" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(GlobalBlacklist)3786": { - "encoding": "inplace", - "label": "contract GlobalBlacklist", - "numberOfBytes": "20" - }, - "t_contract(GlobalOwner)3833": { - "encoding": "inplace", - "label": "contract GlobalOwner", - "numberOfBytes": "20" - }, - "t_contract(GlobalPause)3909": { - "encoding": "inplace", - "label": "contract GlobalPause", - "numberOfBytes": "20" - }, - "t_contract(IERC20Upgradeable)1724": { - "encoding": "inplace", - "label": "contract IERC20Upgradeable", - "numberOfBytes": "20" - }, - "t_contract(ITransfersListener)8840": { - "encoding": "inplace", - "label": "contract ITransfersListener", - "numberOfBytes": "20" - }, - "t_contract(LDYStaking)3669": { - "encoding": "inplace", - "label": "contract LDYStaking", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_address)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => address)", - "numberOfBytes": "32", - "value": "t_address" - }, - "t_mapping(t_address,t_array(t_address)dyn_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => address[])", - "numberOfBytes": "32", - "value": "t_array(t_address)dyn_storage" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_struct(AccountDetails)6024_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => struct InvestUpgradeable.AccountDetails)", - "numberOfBytes": "32", - "value": "t_struct(AccountDetails)6024_storage" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(AccountDetails)6024_storage": { - "encoding": "inplace", - "label": "struct InvestUpgradeable.AccountDetails", - "members": [ - { - "astId": 6021, - "contract": "contracts/src/LToken.sol:LToken", - "label": "period", - "offset": 0, - "slot": "0", - "type": "t_struct(InvestmentPeriod)6018_storage" - }, - { - "astId": 6023, - "contract": "contracts/src/LToken.sol:LToken", - "label": "virtualBalance", - "offset": 0, - "slot": "3", - "type": "t_uint256" - } - ], - "numberOfBytes": "128" - }, - "t_struct(InvestmentPeriod)6018_storage": { - "encoding": "inplace", - "label": "struct InvestUpgradeable.InvestmentPeriod", - "members": [ - { - "astId": 6014, - "contract": "contracts/src/LToken.sol:LToken", - "label": "timestamp", - "offset": 0, - "slot": "0", - "type": "t_uint40" - }, - { - "astId": 6017, - "contract": "contracts/src/LToken.sol:LToken", - "label": "ref", - "offset": 0, - "slot": "1", - "type": "t_struct(Reference)8864_storage" - } - ], - "numberOfBytes": "96" - }, - "t_struct(Pack)8859_storage": { - "encoding": "inplace", - "label": "struct APRHistory.Pack", - "members": [ - { - "astId": 8852, - "contract": "contracts/src/LToken.sol:LToken", - "label": "aprsUD7x3", - "offset": 0, - "slot": "0", - "type": "t_array(t_uint16)4_storage" - }, - { - "astId": 8856, - "contract": "contracts/src/LToken.sol:LToken", - "label": "timestamps", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint40)4_storage" - }, - { - "astId": 8858, - "contract": "contracts/src/LToken.sol:LToken", - "label": "cursor", - "offset": 0, - "slot": "2", - "type": "t_uint32" - } - ], - "numberOfBytes": "96" - }, - "t_struct(Reference)8864_storage": { - "encoding": "inplace", - "label": "struct APRHistory.Reference", - "members": [ - { - "astId": 8861, - "contract": "contracts/src/LToken.sol:LToken", - "label": "packIndex", - "offset": 0, - "slot": "0", - "type": "t_uint256" - }, - { - "astId": 8863, - "contract": "contracts/src/LToken.sol:LToken", - "label": "cursorIndex", - "offset": 0, - "slot": "1", - "type": "t_uint32" - } - ], - "numberOfBytes": "64" - }, - "t_struct(WithdrawalRequest)3951_storage": { - "encoding": "inplace", - "label": "struct LToken.WithdrawalRequest", - "members": [ - { - "astId": 3948, - "contract": "contracts/src/LToken.sol:LToken", - "label": "account", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3950, - "contract": "contracts/src/LToken.sol:LToken", - "label": "amount", - "offset": 20, - "slot": "0", - "type": "t_uint96" - } - ], - "numberOfBytes": "32" - }, - "t_uint16": { - "encoding": "inplace", - "label": "uint16", - "numberOfBytes": "2" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint40": { - "encoding": "inplace", - "label": "uint40", - "numberOfBytes": "5" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - }, - "t_uint96": { - "encoding": "inplace", - "label": "uint96", - "numberOfBytes": "12" - } - } - } -} diff --git a/contracts/hardhat/archive/linea/LUSDC_Implementation_before_Aug_22_upgrade.json b/contracts/hardhat/archive/linea/LUSDC_Implementation_before_Aug_22_upgrade.json deleted file mode 100644 index fb9b42a9..00000000 --- a/contracts/hardhat/archive/linea/LUSDC_Implementation_before_Aug_22_upgrade.json +++ /dev/null @@ -1,2496 +0,0 @@ -{ - "address": "0xB644f32ec6CB162e766289a7b915b02D4611F667", - "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" - } - ], - "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" - } - ], - "transactionHash": "0xc3bc1b1251f53df060ad96ac2de8914c69e86fe44e81efdef0ff7e9118a0b8e7", - "receipt": { - "to": null, - "from": "0x9644fFCE92Ff305f14AF9aCD71c7ccbBE6478023", - "contractAddress": "0xB644f32ec6CB162e766289a7b915b02D4611F667", - "transactionIndex": 0, - "gasUsed": "5328182", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000010000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe778627f301eceb22c2dc24fdc377d3536bc9d830d6adbfd732ab46ff05362d5", - "transactionHash": "0xc3bc1b1251f53df060ad96ac2de8914c69e86fe44e81efdef0ff7e9118a0b8e7", - "logs": [ - { - "transactionIndex": 0, - "blockNumber": 210255, - "transactionHash": "0xc3bc1b1251f53df060ad96ac2de8914c69e86fe44e81efdef0ff7e9118a0b8e7", - "address": "0xB644f32ec6CB162e766289a7b915b02D4611F667", - "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], - "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", - "logIndex": 0, - "blockHash": "0xe778627f301eceb22c2dc24fdc377d3536bc9d830d6adbfd732ab46ff05362d5" - } - ], - "blockNumber": 210255, - "cumulativeGasUsed": "5328182", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "5c79fe53028b0d481f9283fd175451bf", - "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\"}],\"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)\":{\"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.\",\"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)\":{\"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\"},\"contracts/src/DummyLDYStaking.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.18;\\n\\n/**\\n * @title LDYStaking\\n * @author Lila Rest (https://lila.rest)\\n * @custom:security-contact security@ledgity.com\\n *\\n * @notice Replacement of the LDYStaking until the $LDY token is available and the real\\n * LDYStaking contract 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 {\\n /**\\n * @dev Dummy tierOf() function that always return that the given account is not\\n * ellgible to any LDY staking tier.\\n * @param account @\\n */\\n function tierOf(address account) public pure returns (uint256 tier) {\\n account; // Silence unused variable compiler warning\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x8cd4bd13add4048231adb6e74adaecc3958918ae85fd22de106fce63ec806a5e\",\"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 }\\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.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 );\\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\",\"keccak256\":\"0x35bcf57f7debb63a1be92701efc49e806475c124e678235bb84939f4b682da33\",\"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": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051615ef16200011f6000396000818161142301528181611463015281816118b6015281816118f601526119890152615ef16000f3fe6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061540d565b60405180910390f35b34801561041557600080fd5b50610429610424366004615455565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615481565b610cd5565b005b34801561046757600080fd5b50610459610476366004615481565b610d41565b34801561048757600080fd5b5061045961049636600461549e565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f0366004615455565b611037565b34801561050157600080fd5b5061042961051036600461550f565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b50610429610545366004615455565b6113de565b34801561055657600080fd5b5061055f61140f565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615481565b611419565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e5366004615455565b6114f8565b3480156105f657600080fd5b506105b2610605366004615455565b61151a565b34801561061657600080fd5b50610459610625366004615550565b611553565b34801561063657600080fd5b50610459610645366004615550565b611743565b610459610658366004615601565b6118ac565b34801561066957600080fd5b506104b061197c565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a4366004615550565b611a2f565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611a6b565b3480156106f157600080fd5b50610459610700366004615481565b611a75565b34801561071157600080fd5b506104596107203660046156a4565b611bcc565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615481565b611c7d565b34801561077057600080fd5b50610459611c9b565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c2366004615550565b611cd1565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b50610459610801366004615550565b612089565b34801561081257600080fd5b50610459610821366004615455565b61220d565b34801561083257600080fd5b506105b2610841366004615481565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b2612272565b34801561087e57600080fd5b5061045961088d3660046156c1565b6122e1565b34801561089e57600080fd5b506103f3612518565b3480156108b357600080fd5b506104b06108c2366004615481565b612527565b3480156108d357600080fd5b506104596108e2366004615481565b612545565b6104596108f5366004615550565b6125a0565b34801561090657600080fd5b50610429610915366004615455565b612903565b34801561092657600080fd5b50610459610935366004615481565b612989565b34801561094657600080fd5b506104596109553660046156c1565b6129b4565b34801561096657600080fd5b50610429610975366004615455565b612cea565b34801561098657600080fd5b50610459612cf8565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb366004615550565b612de1565b3480156109dc57600080fd5b506109f06109eb366004615455565b612f34565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a20366004615550565b613050565b348015610a3157600080fd5b50610a3a613061565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615481565b6130d9565b348015610af357600080fd5b506104596130e6565b348015610b0857600080fd5b506104b06131a7565b348015610b1d57600080fd5b506104b0610b2c3660046156c1565b61322e565b348015610b3d57600080fd5b50610459610b4c36600461570c565b613259565b348015610b5d57600080fd5b506105b2610b6c366004615550565b613288565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b06132b3565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615481565b6132be565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461570c565b6132f3565b6060609a8054610c3890615729565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6490615729565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc9818585613360565b60019150505b92915050565b610cdd613484565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613484565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed0919081019061575d565b9050610f1d87878784604051602001610ee991906157d4565b60405160208183030381529060405285604051602001610f099190615804565b6040516020818303038152906040526134e5565b610f2683613529565b610f2f30613559565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f73612272565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c612272565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e6132b3565b6110289190615843565b6110329190615843565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613603565b61108185858561367d565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e0613839565b610300546102ff5460009182915b808210156113815761afc85a106113815760006102ff838154811061111557611115615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925291501561136e57805161116490613881565b156111e6576102ff838154811061117d5761117d615856565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa49091015561136e565b60026111f06131a7565b6111fa919061586c565b81602001516001600160601b0316111561128b576102ff838154811061122257611222615856565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9091015561136e565b6000806112a9836000015184602001516001600160601b0316612f34565b91509150856102fe546112bc919061588e565b8211156112cb57505050611381565b6112d58188615843565b96506112e18287615843565b9550600183600001516001600160a01b031686600080516020615e75833981519152866020015186600260405161131a939291906158c3565b60405180910390a46102ff858154811061133657611336615856565b6000918252602082200155825161136b908361135b6102c6546001600160a01b031690565b6001600160a01b031691906138f1565b50505b82611378816158e7565b935050506110ee565b836102fc60008282546113949190615843565b92505081905550826102fe60008282546113ae919061588e565b909155506113be90508484615843565b6102fd60008282546113d0919061588e565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b6000611032613954565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114615760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114aa600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146114d05760405162461bcd60e51b8152600401610d159061594c565b6114d9816139ca565b604080516000808252602082019092526114f5918391906139d2565b50565b600033610cc981858561150b838361322e565b6115159190615843565b613360565b610292602052816000526040600020818154811061153757600080fd5b6000918252602090912001546001600160a01b03169150829050565b61155b613839565b3361156581613881565b156115825760405162461bcd60e51b8152600401610d1590615998565b61158b33611c7d565b8211156115c05760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546115d59190615843565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165b91906159b4565b1015801561166c57506102fe548411155b905081806116775750805b6116a95760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116b63387612f34565b91509150806102fc60008282546116cd9190615843565b92505081905550816102fe60008282546116e7919061588e565b9091555060019050336001600160a01b0316600019600080516020615e758339815191528986600260405161171e939291906159cd565b60405180910390a46117303382613b3d565b61173a3383613c84565b50505050505050565b61174b613839565b3361175581613881565b156117725760405162461bcd60e51b8152600401610d1590615998565b60006102ff838154811061178857611788615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118045760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd6000828254611824919061588e565b90915550506102ff80548490811061183e5761183e615856565b6000918252602082200155600181600001516001600160a01b031684600080516020615e75833981519152846020015185602001516001604051611884939291906159e8565b60405180910390a46118a7816000015182602001516001600160601b0316613cb1565b505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118f45760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661193d600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146119635760405162461bcd60e51b8152600401610d159061594c565b61196c826139ca565b611978828260016139d2565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a1c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615e5583398151915290565b6103018181548110611a4057600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613d86565b611a7d613484565b610302546000199060005b81811015611ae257836001600160a01b03166103028281548110611aae57611aae615856565b6000918252602090912001546001600160a01b031603611ad057809250611ae2565b80611ada816158e7565b915050611a88565b506000198213611b1a5760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b2860018361588e565b81548110611b3857611b38615856565b60009182526020909120015461030280546001600160a01b039092169184908110611b6557611b65615856565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611ba557611ba5615a0d565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611bd4613484565b60405163433e3bad60e11b8152610290600482015261ffff82166024820152733F0Ff9947550d7Cf26549136552C785446ad4Ac59063867c775a9060440160006040518083038186803b158015611c2a57600080fd5b505af4158015611c3e573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611c88826130d9565b611c9183612527565b610ccf9190615843565b611ca3613484565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d1b5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d23613839565b60006102ff8281548110611d3957611d39615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611daa5760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611db590613881565b15611de85760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611df26131a7565b611dfc919061586c565b81602001516001600160601b031611611e3d5760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611e5b836000015184602001516001600160601b0316612f34565b915091506000611e746102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee291906159b4565b9050806102fe54611ef39190615843565b831115611f285760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f3b9190615843565b9250508190555083602001516001600160601b03166102fd6000828254611f62919061588e565b9091555050610300548503611f88576103008054906000611f82836158e7565b91905055505b600184600001516001600160a01b031686600080516020615e758339815191528760200151876002604051611fbf939291906158c3565b60405180910390a46102ff8581548110611fdb57611fdb615856565b600091825260208220015580831161201d57612018338551856120076102c6546001600160a01b031690565b6001600160a01b0316929190613df5565b61207a565b6000612029828561588e565b9050806102fe600082825461203e919061588e565b9091555061205e9050338651846120076102c6546001600160a01b031690565b8451612078908261135b6102c6546001600160a01b031690565b505b612082613e2d565b5050505050565b6102fb546001600160a01b0316336001600160a01b0316146120d35760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6120db613839565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015612132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215691906159b4565b81111561218b5760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe5461219c9190615843565b90506121a66131a7565b8111156121db5760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546121ee9190615843565b9091555061197890503330846120076102c6546001600160a01b031690565b612215613484565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122685760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119788282613e96565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a23565b6122e9613839565b816122f381613881565b156123105760405162461bcd60e51b8152600401610d1590615998565b8161231a81613881565b156123375760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038481166000908152610291602052604090205416156123865760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b0384166123c25760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166123fe5760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124455760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b61244d612272565b6001600160a01b0316336001600160a01b031614806124745750336001600160a01b038516145b6124a65760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124b1846001613f88565b6124bc836001613f88565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c3890615729565b6001600160a01b038116600090815260976020526040812054610ccf565b61254d613484565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125a8613839565b336125b281613881565b156125cf5760405162461bcd60e51b8152600401610d1590615998565b6125d833611c7d565b82111561260d5760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b0382111561264a5760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660e35fa931a0000146126865760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b6000604051806040016040528061269a3390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906159b4565b101580156127475750600061030054115b156127b557610300805490600061275d83615a40565b9190505550610300549050816102ff828154811061277d5761277d615856565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561281f565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec90920191909155905461281c919061588e565b90505b836102fd60008282546128329190615843565b9091555060019050336001600160a01b031682600080516020615e7583398151915287886000604051612867939291906159cd565b60405180910390a46128793385613b3d565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d80600081146128c7576040519150601f19603f3d011682016040523d82523d6000602084013e6128cc565b606091505b50509050806120825760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b60003381612911828661322e565b9050838110156129715760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b61297e8286868403613360565b506001949350505050565b612991613484565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b6129bc613839565b816129c681613881565b156129e35760405162461bcd60e51b8152600401610d1590615998565b816129ed81613881565b15612a0a5760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038416612a465760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612a825760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612a8a612272565b6001600160a01b0316336001600160a01b03161480612ab15750336001600160a01b038516145b612ae35760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b365760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b41846001613f88565b612b4c836001613f88565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612bd7576001600160a01b0385811660009081526102926020526040902080549188169183908110612ba357612ba3615856565b6000918252602090912001546001600160a01b031603612bc557809150612bd7565b80612bcf816158e7565b915050612b52565b506000811215612be957612be9615a57565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c2d9060019061588e565b81548110612c3d57612c3d615856565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612c7b57612c7b615856565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612cc157612cc1615a0d565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561367d565b612d00613484565b60006102fe54612d196102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8391906159b4565b612d8d919061588e565b905060008111612dc55760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b6114f5612ddb6102c6546001600160a01b031690565b82613e96565b612de9613839565b33612df381613881565b15612e105760405162461bcd60e51b8152600401610d1590615998565b81612e246102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9b91906159b4565b1015612ecf5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612ee29190615843565b9091555060009050336001600160a01b0316600019600080516020615e7583398151915285866002604051612f19939291906159cd565b60405180910390a4612f2b338361405d565b50611978613e2d565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fab91906159b4565b10612fbb57508190506000613049565b6000612fd8612fd361028e546001600160a01b031690565b6140de565b90506000612fe6858361414b565b6102fb5490915060009061300790600160a01b900463ffffffff1684614189565b905060006130166064856141b5565b6130208385615a6d565b61302a919061586c565b905061303681856141e3565b9450613042858861588e565b9550505050505b9250929050565b6102ff8181548110611a4057600080fd5b60405163106d64cf60e31b81526102906004820152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063836b267890602401602060405180830381865af41580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a84565b6000610ccf82600161421a565b6130ee613484565b60006102fc54116131275760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131635760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe6000828254613179919061588e565b90915550506102fc805460009091556114f5613193612272565b8261135b6102c6546001600160a01b031690565b6000806131c0612fd361028e546001600160a01b031690565b905060006131d56131cf61100c565b8361414b565b6102fb549091506000906131f690600160c01b900463ffffffff1684614189565b905060006132056064856141b5565b61320f8385615a6d565b613219919061586c565b905061322581856141e3565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b613261613484565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061329957600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6132c6613484565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b6132fb613484565b61271063ffffffff821611156133395760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166133c25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134235760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361348d612272565b6001600160a01b0316146134e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661350c5760405162461bcd60e51b8152600401610d1590615aa1565b613517858585614780565b61352182826147da565b61208261480b565b600054610100900460ff166135505760405162461bcd60e51b8152600401610d1590615aa1565b6114f581614832565b600054610100900460ff166135805760405162461bcd60e51b8152600401610d1590615aa1565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b8152610290600482015260006024820152733F0Ff9947550d7Cf26549136552C785446ad4Ac59063867c775a9060440160006040518083038186803b1580156135ef57600080fd5b505af4158015612082573d6000803e3d6000fd5b600061360f848461322e565b90506000198114613677578181101561366a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136778484848403613360565b50505050565b6001600160a01b0383166136e15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137435760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b61374e8383836148d4565b6001600160a01b038316600090815260976020526040902054818110156137c65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138269086815260200190565b60405180910390a3613677848484614913565b613841611a6b565b156134e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615aec565b6040516001600160a01b0383166024820152604481018290526118a790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a1c565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa9250505080156139bb575060408051601f3d908101601f191682019092526139b891810190615b0e565b60015b6139c55750601290565b919050565b6114f5613484565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a05576118a783614af1565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613a5f575060408051601f3d908101601f19168201909252613a5c918101906159b4565b60015b613ac25760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615e558339815191528114613b315760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118a7838383614b8d565b6001600160a01b038216613b9d5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613ba9826000836148d4565b6001600160a01b03821660009081526097602052604090205481811015613c1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118a783600084614913565b6000613c903383613b3d565b6102c654613ca8906001600160a01b031684846138f1565b50600192915050565b6001600160a01b038216613d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d13600083836148d4565b8060996000828254613d259190615843565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361197860008383614913565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613dd1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615aec565b6040516001600160a01b03808516602483015283166044820152606481018290526136779085906323b872dd60e01b9060840161391d565b6000613e376131a7565b9050806102fe5411613e465750565b6000816102fe54613e57919061588e565b9050806102fe6000828254613e6c919061588e565b90915550506102fb54611978906001600160a01b03168261135b6102c6546001600160a01b031690565b613e9e613484565b60008111613ed45760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4091906159b4565b1015613f745760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118a76001600160a01b03821633846138f1565b6102935460ff1615613f98575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603613fc6575050565b6001600160a01b0380831660009081526102916020526040902054168015613ff2576118a78183613f88565b6000613ffe848461421a565b9050801561405457610293805460ff1916600117905560006140208583614bb2565b610293805460ff19169055905080614052576001600160a01b038516600090815261028f602052604090206003018290555b505b61367784614c09565b6000333081036140bb5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c6546140d4906001600160a01b0316823086613df5565b610cc98484613cb1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561411e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141429190615b0e565b60ff1692915050565b6000600382101561417d5761416182600661588e565b61416c90600a615c15565b6141769084615a6d565b9050610ccf565b611087836103e8615a6d565b600060038210156141a057614176836103e8615a6d565b6141ab82600a615c15565b6110879084615a6d565b600060038210156141cd5761417683620f4240615a6d565b6141d8826003615843565b6141ab90600a615c15565b6000600382101561420e576141f982600661588e565b61420490600a615c15565b614176908461586c565b6110876103e88461586c565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161428b85614d6b565b82515190915064ffffffffff1615806142a2575080155b156142b257600092505050610ccf565b815160200151604051630b27cfb160e31b8152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906142f690610290908690600401615c21565b6040805180830381865af4158015614312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143369190615c45565b60405163038255fd60e11b81526102906004820152909150600090733F0Ff9947550d7Cf26549136552C785446ad4Ac590630704abfa906024016040805180830381865af415801561438c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b09190615c90565b905084602001519550733F0Ff9947550d7Cf26549136552C785446ad4Ac5634ead0c5384836040518363ffffffff1660e01b81526004016143f2929190615cbc565b602060405180830381865af415801561440f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144339190615aec565b61474457604051633e1e5c5360e11b8152600090733F0Ff9947550d7Cf26549136552C785446ad4Ac590637c3cb8a690614471908790600401615cf0565b6040805180830381865af415801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615c90565b604051630b27cfb160e31b8152909150600090733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906144f290610290908690600401615c21565b6040805180830381865af415801561450e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145329190615c45565b87515160208201518651929350614560928c61454f576000614551565b8b5b61455b908b615843565b614e14565b61456a9089615843565b97505b819450809350733F0Ff9947550d7Cf26549136552C785446ad4Ac5634ead0c5386856040518363ffffffff1660e01b81526004016145ac929190615cbc565b602060405180830381865af41580156145c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ed9190615aec565b61471757604051633e1e5c5360e11b8152733F0Ff9947550d7Cf26549136552C785446ad4Ac590637c3cb8a690614628908890600401615cf0565b6040805180830381865af4158015614644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146689190615c90565b604051630b27cfb160e31b8152909250733F0Ff9947550d7Cf26549136552C785446ad4Ac59063593e7d88906146a690610290908690600401615c21565b6040805180830381865af41580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e69190615c45565b90506147068460200151826020015186600001518c61454f576000614551565b6147109089615843565b975061456d565b61473184602001514286600001518c61454f576000614551565b61473b9089615843565b97505050614775565b8451518251614768919042908a61475c57600061475e565b895b61455b9089615843565b6147729087615843565b95505b505050505092915050565b600054610100900460ff166147a75760405162461bcd60e51b8152600401610d1590615aa1565b6147af61480b565b6147b883614f00565b6147c0614f30565b6147c982614f5f565b6147d281614fa9565b6118a761480b565b600054610100900460ff166148015760405162461bcd60e51b8152600401610d1590615aa1565b6119788282614ff3565b600054610100900460ff166134e35760405162461bcd60e51b8152600401610d1590615aa1565b600054610100900460ff166148595760405162461bcd60e51b8152600401610d1590615aa1565b306001600160a01b038216036148b15760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6148df838383615033565b6001600160a01b038316156148f9576148f9836001613f88565b6001600160a01b038216156118a7576118a7826001613f88565b6001600160a01b038316158061493057506001600160a01b038216155b15614970577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f61495e61100c565b60405190815260200160405180910390a15b60005b6103025481101561367757610302818154811061499257614992615856565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b1580156149f157600080fd5b505af1158015614a05573d6000803e3d6000fd5b505050508080614a14906158e7565b915050614973565b6000614a71826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150949092919063ffffffff16565b9050805160001480614a92575080806020019051810190614a929190615aec565b6118a75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614b5e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615e5583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614b96836150a3565b600082511180614ba35750805b156118a75761367783836150e3565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614be885612527565b60408051918252602082018690520160405180910390a2613ca88383613cb1565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b81526102906004820152733F0Ff9947550d7Cf26549136552C785446ad4Ac590630704abfa906024016040805180830381865af4158015614c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cab9190615c90565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b03821660009081526102926020526040902054811015611978576001600160a01b0382166000908152610292602052604090208054614d59919083908110614d3f57614d3f615856565b6000918252602090912001546001600160a01b0316614c09565b80614d63816158e7565b915050614cee565b6000614d7682615108565b614d809082615843565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e0e576001600160a01b0383166000908152610292602052604090208054614df0919083908110614dd657614dd6615856565b6000918252602090912001546001600160a01b0316614d6b565b614dfa9083615843565b915080614e06816158e7565b915050614d85565b50919050565b600080614e2d612fd361028e546001600160a01b031690565b90506000614e4b614e3e8888615d0d565b64ffffffffff16836141b5565b90506000614e5d6301e13380846141b5565b614e686001856141b5565b614e729084615a6d565b614e7c919061586c565b90506000614e8e8761ffff1685614189565b90506000614e9d6001866141b5565b614ea78385615a6d565b614eb1919061586c565b90506000614ebf888761414b565b90506000614ece6064886141b5565b614ed88484615a6d565b614ee2919061586c565b9050614eee81886141e3565b9750505050505050505b949350505050565b600054610100900460ff16614f275760405162461bcd60e51b8152600401610d1590615aa1565b6114f581615113565b600054610100900460ff16614f575760405162461bcd60e51b8152600401610d1590615aa1565b6134e361515d565b600054610100900460ff16614f865760405162461bcd60e51b8152600401610d1590615aa1565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16614fd05760405162461bcd60e51b8152600401610d1590615aa1565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661501a5760405162461bcd60e51b8152600401610d1590615aa1565b609a6150268382615d78565b50609b6118a78282615d78565b61503b613839565b8261504581613881565b156150625760405162461bcd60e51b8152600401610d1590615998565b8261506c81613881565b156150895760405162461bcd60e51b8152600401610d1590615998565b612082858585615190565b6060614ef884846000856151f8565b6150ac81614af1565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615e95602791396152d3565b6000610ccf82612527565b600054610100900460ff1661513a5760405162461bcd60e51b8152600401610d1590615aa1565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151845760405162461bcd60e51b8152600401610d1590615aa1565b60c9805460ff19169055565b615198611a6b565b156118a75760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152759190615e38565b60006040518083038185875af1925050503d80600081146152b2576040519150601f19603f3d011682016040523d82523d6000602084013e6152b7565b606091505b50915091506152c88783838761534b565b979650505050505050565b6060600080856001600160a01b0316856040516152f09190615e38565b600060405180830381855af49150503d806000811461532b576040519150601f19603f3d011682016040523d82523d6000602084013e615330565b606091505b50915091506153418683838761534b565b9695505050505050565b606083156153ba5782516000036153b3576001600160a01b0385163b6153b35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614ef8565b614ef883838151156153cf5781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061540d565b60005b838110156154045781810151838201526020016153ec565b50506000910152565b602081526000825180602084015261542c8160408501602087016153e9565b601f01601f19169190910160400192915050565b6001600160a01b03811681146114f557600080fd5b6000806040838503121561546857600080fd5b823561547381615440565b946020939093013593505050565b60006020828403121561549357600080fd5b813561108781615440565b600080600080600060a086880312156154b657600080fd5b85356154c181615440565b945060208601356154d181615440565b935060408601356154e181615440565b925060608601356154f181615440565b9150608086013561550181615440565b809150509295509295909350565b60008060006060848603121561552457600080fd5b833561552f81615440565b9250602084013561553f81615440565b929592945050506040919091013590565b60006020828403121561556257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155a2576155a2615569565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156155d1576155d1615569565b604052919050565b600067ffffffffffffffff8211156155f3576155f3615569565b50601f01601f191660200190565b6000806040838503121561561457600080fd5b823561561f81615440565b9150602083013567ffffffffffffffff81111561563b57600080fd5b8301601f8101851361564c57600080fd5b803561565f61565a826155d9565b6155a8565b81815286602083850101111561567457600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff811681146114f557600080fd5b6000602082840312156156b657600080fd5b813561108781615694565b600080604083850312156156d457600080fd5b82356156df81615440565b915060208301356156ef81615440565b809150509250929050565b63ffffffff811681146114f557600080fd5b60006020828403121561571e57600080fd5b8135611087816156fa565b600181811c9082168061573d57607f821691505b602082108103614e0e57634e487b7160e01b600052602260045260246000fd5b60006020828403121561576f57600080fd5b815167ffffffffffffffff81111561578657600080fd5b8201601f8101841361579757600080fd5b80516157a561565a826155d9565b8181528560208385010111156157ba57600080fd5b6157cb8260208301602086016153e9565b95945050505050565b6702632b233b4ba3c960c51b8152600082516157f78160088501602087016153e9565b9190910160080192915050565b601360fa1b8152600082516158208160018501602087016153e9565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf61582d565b634e487b7160e01b600052603260045260246000fd5b60008261588957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ccf57610ccf61582d565b600381106158bf57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03841681526020810183905260608101614ef860408301846158a1565b6000600182016158f9576158f961582d565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b6000602082840312156159c657600080fd5b5051919050565b8381526020810183905260608101614ef860408301846158a1565b6001600160601b0384811682528316602082015260608101614ef860408301846158a1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a3557600080fd5b815161108781615440565b600081615a4f57615a4f61582d565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf61582d565b600060208284031215615a9657600080fd5b815161108781615694565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615afe57600080fd5b8151801515811461108757600080fd5b600060208284031215615b2057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615b6c578160001904821115615b5257615b5261582d565b80851615615b5f57918102915b93841c9390800290615b36565b509250929050565b600082615b8357506001610ccf565b81615b9057506000610ccf565b8160018114615ba65760028114615bb057615bcc565b6001915050610ccf565b60ff841115615bc157615bc161582d565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615bef575081810a610ccf565b615bf98383615b31565b8060001904821115615c0d57615c0d61582d565b029392505050565b60006110878383615b74565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615c5757600080fd5b615c5f61557f565b8251615c6a81615694565b8152602083015164ffffffffff81168114615c8457600080fd5b60208201529392505050565b600060408284031215615ca257600080fd5b615caa61557f565b825181526020830151615c84816156fa565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d2b57615d2b61582d565b5092915050565b601f8211156118a757600081815260208120601f850160051c81016020861015615d595750805b601f850160051c820191505b8181101561100457828155600101615d65565b815167ffffffffffffffff811115615d9257615d92615569565b615da681615da08454615729565b84615d32565b602080601f831160018114615ddb5760008415615dc35750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e0a57888601518255948401946001909101908401615deb565b5085821015615e285787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615e4a8184602087016153e9565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcfeb6a900a360475a17ff2a61d90610bd38f52b2b474c52828b8411221ff2576f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e1d4dd61867ca96be7efe83d7ca66dcd56b3ec13ae334b24d813c7fd7fe3c42d64736f6c63430008120033", - "deployedBytecode": "0x6080604052600436106103d95760003560e01c80638980f11f116101fd578063c822adda11610118578063dd62ed3e116100ab578063ef356a791161007a578063ef356a7914610b96578063f12d54d814610bab578063f2fde38b14610bca578063f762e73414610bea578063f94ce2c214610c0957600080fd5b8063dd62ed3e14610b11578063ee1335d114610b31578063ee153c4f14610b51578063ef2591af14610b7157600080fd5b8063d038875c116100e7578063d038875c14610a8d578063d039981b14610ac7578063d294f09314610ae7578063db84faac14610afc57600080fd5b8063c822adda14610a05578063c89d5b8b14610a25578063cafb220214610a4d578063cdc1842414610a6c57600080fd5b8063a457c2d711610190578063b2de2a431161015f578063b2de2a431461097a578063b60d42881461098f578063b6b55f25146109b0578063bacd609e146109d057600080fd5b8063a457c2d7146108fa578063a64c91cc1461091a578063a8f763201461093a578063a9059cbb1461095a57600080fd5b806395d89b41116101cc57806395d89b411461089257806399a03c70146108a75780639c271975146108c75780639ee679e8146108e757600080fd5b80638980f11f146108065780638d8e6bd7146108265780638da5cb5b1461085d57806392e5ced71461087257600080fd5b80634134bee9116102f85780636d3a4ac81161028b578063734d82871161025a578063734d8287146107795780637594d0b51461079057806375a5652b146107a75780637c2edb16146107c75780638370e1f7146107e657600080fd5b80636d3a4ac8146107055780636f307dc31461072557806370a0823114610744578063715018a61461076457600080fd5b806353ac4b66116102c757806353ac4b661461067257806353d3a42f146106895780635c975abb146106d05780635f0e8e37146106e557600080fd5b80634134bee91461060a57806345b05d091461062a5780634f1ef2861461064a57806352d1902d1461065d57600080fd5b806323b872dd116103705780633659cfe61161033f5780633659cfe614610571578063391d85ec1461059157806339509351146105ca5780633e7ae353146105ea57600080fd5b806323b872dd146104f55780632a1b8b1c146105155780632f4f21e21461052a578063313ce5671461054a57600080fd5b80631459457a116103ac5780631459457a1461047b57806318160ddd1461049b5780631c19be6d146104be578063205c2878146104d557600080fd5b806306fdde03146103de578063095ea7b3146104095780630d174c24146104395780630e21750f1461045b575b600080fd5b3480156103ea57600080fd5b506103f3610c29565b604051610400919061540d565b60405180910390f35b34801561041557600080fd5b50610429610424366004615455565b610cbb565b6040519015158152602001610400565b34801561044557600080fd5b50610459610454366004615481565b610cd5565b005b34801561046757600080fd5b50610459610476366004615481565b610d41565b34801561048757600080fd5b5061045961049636600461549e565b610da8565b3480156104a757600080fd5b506104b061100c565b604051908152602001610400565b3480156104ca57600080fd5b506104b06102fe5481565b3480156104e157600080fd5b506104296104f0366004615455565b611037565b34801561050157600080fd5b5061042961051036600461550f565b611068565b34801561052157600080fd5b5061045961108e565b34801561053657600080fd5b50610429610545366004615455565b6113de565b34801561055657600080fd5b5061055f61140f565b60405160ff9091168152602001610400565b34801561057d57600080fd5b5061045961058c366004615481565b611419565b34801561059d57600080fd5b506102f9546105b2906001600160a01b031681565b6040516001600160a01b039091168152602001610400565b3480156105d657600080fd5b506104296105e5366004615455565b6114f8565b3480156105f657600080fd5b506105b2610605366004615455565b61151a565b34801561061657600080fd5b50610459610625366004615550565b611553565b34801561063657600080fd5b50610459610645366004615550565b611743565b610459610658366004615601565b6118ac565b34801561066957600080fd5b506104b061197c565b34801561067e57600080fd5b506104b06102fd5481565b34801561069557600080fd5b506106a96106a4366004615550565b611a2f565b604080516001600160a01b0390931683526001600160601b03909116602083015201610400565b3480156106dc57600080fd5b50610429611a6b565b3480156106f157600080fd5b50610459610700366004615481565b611a75565b34801561071157600080fd5b506104596107203660046156a4565b611bcc565b34801561073157600080fd5b506102c6546001600160a01b03166105b2565b34801561075057600080fd5b506104b061075f366004615481565b611c7d565b34801561077057600080fd5b50610459611c9b565b34801561078557600080fd5b506104b06102fc5481565b34801561079c57600080fd5b506104b06103005481565b3480156107b357600080fd5b506104596107c2366004615550565b611cd1565b3480156107d357600080fd5b50610193546001600160a01b03166105b2565b3480156107f257600080fd5b50610459610801366004615550565b612089565b34801561081257600080fd5b50610459610821366004615455565b61220d565b34801561083257600080fd5b506105b2610841366004615481565b610291602052600090815260409020546001600160a01b031681565b34801561086957600080fd5b506105b2612272565b34801561087e57600080fd5b5061045961088d3660046156c1565b6122e1565b34801561089e57600080fd5b506103f3612518565b3480156108b357600080fd5b506104b06108c2366004615481565b612527565b3480156108d357600080fd5b506104596108e2366004615481565b612545565b6104596108f5366004615550565b6125a0565b34801561090657600080fd5b50610429610915366004615455565b612903565b34801561092657600080fd5b50610459610935366004615481565b612989565b34801561094657600080fd5b506104596109553660046156c1565b6129b4565b34801561096657600080fd5b50610429610975366004615455565b612cea565b34801561098657600080fd5b50610459612cf8565b34801561099b57600080fd5b506102fb546105b2906001600160a01b031681565b3480156109bc57600080fd5b506104596109cb366004615550565b612de1565b3480156109dc57600080fd5b506109f06109eb366004615455565b612f34565b60408051928352602083019190915201610400565b348015610a1157600080fd5b506106a9610a20366004615550565b613050565b348015610a3157600080fd5b50610a3a613061565b60405161ffff9091168152602001610400565b348015610a5957600080fd5b5061028e546001600160a01b03166105b2565b348015610a7857600080fd5b506102fa546105b2906001600160a01b031681565b348015610a9957600080fd5b506102fb54610ab290600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610400565b348015610ad357600080fd5b506104b0610ae2366004615481565b6130d9565b348015610af357600080fd5b506104596130e6565b348015610b0857600080fd5b506104b06131a7565b348015610b1d57600080fd5b506104b0610b2c3660046156c1565b61322e565b348015610b3d57600080fd5b50610459610b4c36600461570c565b613259565b348015610b5d57600080fd5b506105b2610b6c366004615550565b613288565b348015610b7d57600080fd5b506102fb54610ab290600160c01b900463ffffffff1681565b348015610ba257600080fd5b506104b06132b3565b348015610bb757600080fd5b50610160546001600160a01b03166105b2565b348015610bd657600080fd5b50610459610be5366004615481565b6132be565b348015610bf657600080fd5b5061012d546001600160a01b03166105b2565b348015610c1557600080fd5b50610459610c2436600461570c565b6132f3565b6060609a8054610c3890615729565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6490615729565b8015610cb15780601f10610c8657610100808354040283529160200191610cb1565b820191906000526020600020905b815481529060010190602001808311610c9457829003601f168201915b5050505050905090565b600033610cc9818585613360565b60019150505b92915050565b610cdd613484565b6001600160a01b038116610d1e5760405162461bcd60e51b81526020600482015260036024820152624c363360e81b60448201526064015b60405180910390fd5b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055565b610d49613484565b6001600160a01b038116610d855760405162461bcd60e51b8152602060048201526003602482015262130d8d60ea1b6044820152606401610d15565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1615808015610dc85750600054600160ff909116105b80610de25750303b158015610de2575060005460ff166001145b610e455760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d15565b6000805460ff191660011790558015610e68576000805461ff0019166101001790555b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610ea8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ed0919081019061575d565b9050610f1d87878784604051602001610ee991906157d4565b60405160208183030381529060405285604051602001610f099190615804565b6040516020818303038152906040526134e5565b610f2683613529565b610f2f30613559565b6102f980546001600160a01b0319166001600160a01b0386161790556102fb805467ffffffffffffffff60a01b19166509c40000004b60a21b179055610f73612272565b6102fa80546001600160a01b0319166001600160a01b0392909216919091179055610f9c612272565b6102fb80546001600160a01b0319166001600160a01b0392909216919091179055508015611004576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60006102fc546102fd5461101e6132b3565b6110289190615843565b6110329190615843565b905090565b60405162461bcd60e51b81526020600482015260036024820152624c343560e81b6044820152600090606401610d15565b600033611076858285613603565b61108185858561367d565b60019150505b9392505050565b6102fa546001600160a01b0316336001600160a01b0316146110d85760405162461bcd60e51b81526020600482015260036024820152624c333960e81b6044820152606401610d15565b6110e0613839565b610300546102ff5460009182915b808210156113815761afc85a106113815760006102ff838154811061111557611115615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925291501561136e57805161116490613881565b156111e6576102ff838154811061117d5761117d615856565b60009182526020808320909101829055610301805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177fe78f8e39db67a8c6e0d54c288efc6f296f5d558bc028138a8476c9b97f6fcaa49091015561136e565b60026111f06131a7565b6111fa919061586c565b81602001516001600160601b0316111561128b576102ff838154811061122257611222615856565b600091825260208083209091018290556102ff805460018101825592528251908301516001600160601b0316600160a01b026001600160a01b0391909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec9091015561136e565b6000806112a9836000015184602001516001600160601b0316612f34565b91509150856102fe546112bc919061588e565b8211156112cb57505050611381565b6112d58188615843565b96506112e18287615843565b9550600183600001516001600160a01b031686600080516020615e75833981519152866020015186600260405161131a939291906158c3565b60405180910390a46102ff858154811061133657611336615856565b6000918252602082200155825161136b908361135b6102c6546001600160a01b031690565b6001600160a01b031691906138f1565b50505b82611378816158e7565b935050506110ee565b836102fc60008282546113949190615843565b92505081905550826102fe60008282546113ae919061588e565b909155506113be90508484615843565b6102fd60008282546113d0919061588e565b909155505050610300555050565b60405162461bcd60e51b8152602060048201526003602482015262261a1b60e91b6044820152600090606401610d15565b6000611032613954565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114615760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166114aa600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146114d05760405162461bcd60e51b8152600401610d159061594c565b6114d9816139ca565b604080516000808252602082019092526114f5918391906139d2565b50565b600033610cc981858561150b838361322e565b6115159190615843565b613360565b610292602052816000526040600020818154811061153757600080fd5b6000918252602090912001546001600160a01b03169150829050565b61155b613839565b3361156581613881565b156115825760405162461bcd60e51b8152600401610d1590615998565b61158b33611c7d565b8211156115c05760405162461bcd60e51b815260206004820152600360248201526209868760eb1b6044820152606401610d15565b60006102fe54836102fd546115d59190615843565b6102f95491101591506000906002906001600160a01b031663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611637573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165b91906159b4565b1015801561166c57506102fe548411155b905081806116775750805b6116a95760405162461bcd60e51b81526020600482015260036024820152624c343960e81b6044820152606401610d15565b6000806116b63387612f34565b91509150806102fc60008282546116cd9190615843565b92505081905550816102fe60008282546116e7919061588e565b9091555060019050336001600160a01b0316600019600080516020615e758339815191528986600260405161171e939291906159cd565b60405180910390a46117303382613b3d565b61173a3383613c84565b50505050505050565b61174b613839565b3361175581613881565b156117725760405162461bcd60e51b8152600401610d1590615998565b60006102ff838154811061178857611788615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150336001600160a01b0316146118045760405162461bcd60e51b81526020600482015260036024820152624c353760e81b6044820152606401610d15565b80602001516001600160601b03166102fd6000828254611824919061588e565b90915550506102ff80548490811061183e5761183e615856565b6000918252602082200155600181600001516001600160a01b031684600080516020615e75833981519152846020015185602001516001604051611884939291906159e8565b60405180910390a46118a7816000015182602001516001600160601b0316613cb1565b505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118f45760405162461bcd60e51b8152600401610d1590615900565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661193d600080516020615e55833981519152546001600160a01b031690565b6001600160a01b0316146119635760405162461bcd60e51b8152600401610d159061594c565b61196c826139ca565b611978828260016139d2565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a1c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610d15565b50600080516020615e5583398151915290565b6103018181548110611a4057600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b90046001600160601b031682565b6000611032613d86565b611a7d613484565b610302546000199060005b81811015611ae257836001600160a01b03166103028281548110611aae57611aae615856565b6000918252602090912001546001600160a01b031603611ad057809250611ae2565b80611ada816158e7565b915050611a88565b506000198213611b1a5760405162461bcd60e51b8152602060048201526003602482015262261a1960e91b6044820152606401610d15565b610302611b2860018361588e565b81548110611b3857611b38615856565b60009182526020909120015461030280546001600160a01b039092169184908110611b6557611b65615856565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610302805480611ba557611ba5615a0d565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b611bd4613484565b60405163433e3bad60e11b8152610290600482015261ffff8216602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b158015611c2a57600080fd5b505af4158015611c3e573d6000803e3d6000fd5b505060405161ffff841681527f3d6d63f501ae621a01c729938fb4428a25138835257943d6b56c49b402ba36329250602001905060405180910390a150565b6000611c88826130d9565b611c9183612527565b610ccf9190615843565b611ca3613484565b60405162461bcd60e51b81526020600482015260036024820152624c363560e81b6044820152606401610d15565b6102fb546001600160a01b0316336001600160a01b031614611d1b5760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b611d23613839565b60006102ff8281548110611d3957611d39615856565b6000918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092529150611daa5760405162461bcd60e51b8152602060048201526003602482015262261b1b60e91b6044820152606401610d15565b8051611db590613881565b15611de85760405162461bcd60e51b815260206004820152600360248201526204c35360ec1b6044820152606401610d15565b6002611df26131a7565b611dfc919061586c565b81602001516001600160601b031611611e3d5760405162461bcd60e51b81526020600482015260036024820152624c353160e81b6044820152606401610d15565b600080611e5b836000015184602001516001600160601b0316612f34565b915091506000611e746102c6546001600160a01b031690565b6102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611ebe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee291906159b4565b9050806102fe54611ef39190615843565b831115611f285760405162461bcd60e51b8152602060048201526003602482015262261a9960e91b6044820152606401610d15565b816102fc6000828254611f3b9190615843565b9250508190555083602001516001600160601b03166102fd6000828254611f62919061588e565b9091555050610300548503611f88576103008054906000611f82836158e7565b91905055505b600184600001516001600160a01b031686600080516020615e758339815191528760200151876002604051611fbf939291906158c3565b60405180910390a46102ff8581548110611fdb57611fdb615856565b600091825260208220015580831161201d57612018338551856120076102c6546001600160a01b031690565b6001600160a01b0316929190613df5565b61207a565b6000612029828561588e565b9050806102fe600082825461203e919061588e565b9091555061205e9050338651846120076102c6546001600160a01b031690565b8451612078908261135b6102c6546001600160a01b031690565b505b612082613e2d565b5050505050565b6102fb546001600160a01b0316336001600160a01b0316146120d35760405162461bcd60e51b815260206004820152600360248201526204c34360ec1b6044820152606401610d15565b6120db613839565b6102c6546001600160a01b03166102fb546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015612132573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061215691906159b4565b81111561218b5760405162461bcd60e51b81526020600482015260036024820152620986a760eb1b6044820152606401610d15565b6000816102fe5461219c9190615843565b90506121a66131a7565b8111156121db5760405162461bcd60e51b81526020600482015260036024820152624c353960e81b6044820152606401610d15565b816102fe60008282546121ee9190615843565b9091555061197890503330846120076102c6546001600160a01b031690565b612215613484565b6102c6546001600160a01b03166001600160a01b0316826001600160a01b0316036122685760405162461bcd60e51b81526020600482015260036024820152624c343360e81b6044820152606401610d15565b6119788282613e96565b61012d5460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b9160048083019260209291908290030181865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a23565b6122e9613839565b816122f381613881565b156123105760405162461bcd60e51b8152600401610d1590615998565b8161231a81613881565b156123375760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038481166000908152610291602052604090205416156123865760405162461bcd60e51b8152602060048201526003602482015262261b1960e91b6044820152606401610d15565b6001600160a01b0384166123c25760405162461bcd60e51b815260206004820152600360248201526226189960e91b6044820152606401610d15565b6001600160a01b0383166123fe5760405162461bcd60e51b81526020600482015260036024820152624c313360e81b6044820152606401610d15565b826001600160a01b0316846001600160a01b0316036124455760405162461bcd60e51b8152602060048201526003602482015262130c4d60ea1b6044820152606401610d15565b61244d612272565b6001600160a01b0316336001600160a01b031614806124745750336001600160a01b038516145b6124a65760405162461bcd60e51b81526020600482015260036024820152624c313560e81b6044820152606401610d15565b6124b1846001613f88565b6124bc836001613f88565b50506001600160a01b039182166000818152610291602090815260408083208054969095166001600160a01b03199687168117909555938252610292815292812080546001810182559082529290209091018054909216179055565b6060609b8054610c3890615729565b6001600160a01b038116600090815260976020526040812054610ccf565b61254d613484565b61030280546001810182556000919091527f552430c2010355dda19e8bae437f75cfb136cb8d667c4c0867367db21eee69b60180546001600160a01b0319166001600160a01b0392909216919091179055565b6125a8613839565b336125b281613881565b156125cf5760405162461bcd60e51b8152600401610d1590615998565b6125d833611c7d565b82111561260d5760405162461bcd60e51b81526020600482015260036024820152624c353360e81b6044820152606401610d15565b6001600160601b0382111561264a5760405162461bcd60e51b8152602060048201526003602482015262130d4d60ea1b6044820152606401610d15565b34660e35fa931a0000146126865760405162461bcd60e51b81526020600482015260036024820152624c353560e81b6044820152606401610d15565b6000604051806040016040528061269a3390565b6001600160a01b0390811682526001600160601b0386166020909201919091526102f9549192506000916002911663c8f74bb8336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906159b4565b101580156127475750600061030054115b156127b557610300805490600061275d83615a40565b9190505550610300549050816102ff828154811061277d5761277d615856565b6000918252602091829020835193909201516001600160601b0316600160a01b026001600160a01b039093169290921791015561281f565b6102ff8054600181810183556000839052845160208601516001600160601b0316600160a01b026001600160a01b03909116177f5a4a1f748f8cfa795b59cdc37192794ee567e6029e925719381be08d7ccaf4ec90920191909155905461281c919061588e565b90505b836102fd60008282546128329190615843565b9091555060019050336001600160a01b031682600080516020615e7583398151915287886000604051612867939291906159cd565b60405180910390a46128793385613b3d565b6102fa546040516000916001600160a01b03169034908381818185875af1925050503d80600081146128c7576040519150601f19603f3d011682016040523d82523d6000602084013e6128cc565b606091505b50509050806120825760405162461bcd60e51b8152602060048201526003602482015262261a9b60e91b6044820152606401610d15565b60003381612911828661322e565b9050838110156129715760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d15565b61297e8286868403613360565b506001949350505050565b612991613484565b6102f980546001600160a01b0319166001600160a01b0392909216919091179055565b6129bc613839565b816129c681613881565b156129e35760405162461bcd60e51b8152600401610d1590615998565b816129ed81613881565b15612a0a5760405162461bcd60e51b8152600401610d1590615998565b6001600160a01b038416612a465760405162461bcd60e51b815260206004820152600360248201526226189b60e91b6044820152606401610d15565b6001600160a01b038316612a825760405162461bcd60e51b81526020600482015260036024820152624c313760e81b6044820152606401610d15565b612a8a612272565b6001600160a01b0316336001600160a01b03161480612ab15750336001600160a01b038516145b612ae35760405162461bcd60e51b815260206004820152600360248201526209862760eb1b6044820152606401610d15565b6001600160a01b0384811660009081526102916020526040902054811690841614612b365760405162461bcd60e51b81526020600482015260036024820152624c313960e81b6044820152606401610d15565b612b41846001613f88565b612b4c836001613f88565b60001960005b6001600160a01b03851660009081526102926020526040902054811015612bd7576001600160a01b0385811660009081526102926020526040902080549188169183908110612ba357612ba3615856565b6000918252602090912001546001600160a01b031603612bc557809150612bd7565b80612bcf816158e7565b915050612b52565b506000811215612be957612be9615a57565b6001600160a01b0380861660009081526102916020908152604080832080546001600160a01b031916905592871682526102929052208054612c2d9060019061588e565b81548110612c3d57612c3d615856565b60009182526020808320909101546001600160a01b0387811684526102929092526040909220805491909216919083908110612c7b57612c7b615856565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918616815261029290915260409020805480612cc157612cc1615a0d565b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600033610cc981858561367d565b612d00613484565b60006102fe54612d196102c6546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8391906159b4565b612d8d919061588e565b905060008111612dc55760405162461bcd60e51b8152602060048201526003602482015262130d0d60ea1b6044820152606401610d15565b6114f5612ddb6102c6546001600160a01b031690565b82613e96565b612de9613839565b33612df381613881565b15612e105760405162461bcd60e51b8152600401610d1590615998565b81612e246102c6546001600160a01b031690565b6001600160a01b03166370a08231336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612e77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e9b91906159b4565b1015612ecf5760405162461bcd60e51b81526020600482015260036024820152624c343760e81b6044820152606401610d15565b816102fe6000828254612ee29190615843565b9091555060009050336001600160a01b0316600019600080516020615e7583398151915285866002604051612f19939291906159cd565b60405180910390a4612f2b338361405d565b50611978613e2d565b6102f95460405163191ee97760e31b81526001600160a01b03848116600483015260009283926002929091169063c8f74bb890602401602060405180830381865afa158015612f87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fab91906159b4565b10612fbb57508190506000613049565b6000612fd8612fd361028e546001600160a01b031690565b6140de565b90506000612fe6858361414b565b6102fb5490915060009061300790600160a01b900463ffffffff1684614189565b905060006130166064856141b5565b6130208385615a6d565b61302a919061586c565b905061303681856141e3565b9450613042858861588e565b9550505050505b9250929050565b6102ff8181548110611a4057600080fd5b60405163106d64cf60e31b8152610290600482015260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063836b267890602401602060405180830381865af41580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615a84565b6000610ccf82600161421a565b6130ee613484565b60006102fc54116131275760405162461bcd60e51b815260206004820152600360248201526204c36360ec1b6044820152606401610d15565b6102fc546102fe5410156131635760405162461bcd60e51b81526020600482015260036024820152624c363160e81b6044820152606401610d15565b6102fc546102fe6000828254613179919061588e565b90915550506102fc805460009091556114f5613193612272565b8261135b6102c6546001600160a01b031690565b6000806131c0612fd361028e546001600160a01b031690565b905060006131d56131cf61100c565b8361414b565b6102fb549091506000906131f690600160c01b900463ffffffff1684614189565b905060006132056064856141b5565b61320f8385615a6d565b613219919061586c565b905061322581856141e3565b94505050505090565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b613261613484565b6102fb805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b610302818154811061329957600080fd5b6000918252602090912001546001600160a01b0316905081565b600061103260995490565b6132c6613484565b60405162461bcd60e51b8152602060048201526002602482015261098760f31b6044820152606401610d15565b6132fb613484565b61271063ffffffff821611156133395760405162461bcd60e51b81526020600482015260036024820152624c343160e81b6044820152606401610d15565b6102fb805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6001600160a01b0383166133c25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d15565b6001600160a01b0382166134235760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d15565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b3361348d612272565b6001600160a01b0316146134e35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d15565b565b600054610100900460ff1661350c5760405162461bcd60e51b8152600401610d1590615aa1565b613517858585614780565b61352182826147da565b61208261480b565b600054610100900460ff166135505760405162461bcd60e51b8152600401610d1590615aa1565b6114f581614832565b600054610100900460ff166135805760405162461bcd60e51b8152600401610d1590615aa1565b61028e80546001600160a01b0319166001600160a01b03831617905560405163433e3bad60e11b815261029060048201526000602482015273__$3728f51d90da6977d2525dcec632daa0b3$__9063867c775a9060440160006040518083038186803b1580156135ef57600080fd5b505af4158015612082573d6000803e3d6000fd5b600061360f848461322e565b90506000198114613677578181101561366a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d15565b6136778484848403613360565b50505050565b6001600160a01b0383166136e15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d15565b6001600160a01b0382166137435760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d15565b61374e8383836148d4565b6001600160a01b038316600090815260976020526040902054818110156137c65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d15565b6001600160a01b0380851660008181526097602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906138269086815260200190565b60405180910390a3613677848484614913565b613841611a6b565b156134e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d15565b6101935460405163fe575a8760e01b81526001600160a01b038381166004830152600092169063fe575a8790602401602060405180830381865afa1580156138cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccf9190615aec565b6040516001600160a01b0383166024820152604481018290526118a790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a1c565b6102c6546040805163313ce56760e01b815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa9250505080156139bb575060408051601f3d908101601f191682019092526139b891810190615b0e565b60015b6139c55750601290565b919050565b6114f5613484565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613a05576118a783614af1565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015613a5f575060408051601f3d908101601f19168201909252613a5c918101906159b4565b60015b613ac25760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610d15565b600080516020615e558339815191528114613b315760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610d15565b506118a7838383614b8d565b6001600160a01b038216613b9d5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d15565b613ba9826000836148d4565b6001600160a01b03821660009081526097602052604090205481811015613c1d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d15565b6001600160a01b03831660008181526097602090815260408083208686039055609980548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36118a783600084614913565b6000613c903383613b3d565b6102c654613ca8906001600160a01b031684846138f1565b50600192915050565b6001600160a01b038216613d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d15565b613d13600083836148d4565b8060996000828254613d259190615843565b90915550506001600160a01b0382166000818152609760209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361197860008383614913565b6101605460408051635c975abb60e01b815290516000926001600160a01b031691635c975abb9160048083019260209291908290030181865afa158015613dd1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110329190615aec565b6040516001600160a01b03808516602483015283166044820152606481018290526136779085906323b872dd60e01b9060840161391d565b6000613e376131a7565b9050806102fe5411613e465750565b6000816102fe54613e57919061588e565b9050806102fe6000828254613e6c919061588e565b90915550506102fb54611978906001600160a01b03168261135b6102c6546001600160a01b031690565b613e9e613484565b60008111613ed45760405162461bcd60e51b815260206004820152600360248201526204c31360ec1b6044820152606401610d15565b6040516370a0823160e01b8152306004820152829082906001600160a01b038316906370a0823190602401602060405180830381865afa158015613f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4091906159b4565b1015613f745760405162461bcd60e51b81526020600482015260036024820152624c313160e81b6044820152606401610d15565b6118a76001600160a01b03821633846138f1565b6102935460ff1615613f98575050565b6001600160a01b038216600090815261028f602052604090205464ffffffffff428116911603613fc6575050565b6001600160a01b0380831660009081526102916020526040902054168015613ff2576118a78183613f88565b6000613ffe848461421a565b9050801561405457610293805460ff1916600117905560006140208583614bb2565b610293805460ff19169055905080614052576001600160a01b038516600090815261028f602052604090206003018290555b505b61367784614c09565b6000333081036140bb5760405162461bcd60e51b815260206004820152602360248201527f4552433230577261707065723a20777261707065722063616e2774206465706f6044820152621cda5d60ea1b6064820152608401610d15565b6102c6546140d4906001600160a01b0316823086613df5565b610cc98484613cb1565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561411e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141429190615b0e565b60ff1692915050565b6000600382101561417d5761416182600661588e565b61416c90600a615c15565b6141769084615a6d565b9050610ccf565b611087836103e8615a6d565b600060038210156141a057614176836103e8615a6d565b6141ab82600a615c15565b6110879084615a6d565b600060038210156141cd5761417683620f4240615a6d565b6141d8826003615843565b6141ab90600a615c15565b6000600382101561420e576141f982600661588e565b61420490600a615c15565b614176908461586c565b6110876103e88461586c565b6001600160a01b038216600090815261028f602090815260408083208151608081018352815464ffffffffff16818401908152835180850190945260018301548452600283015463ffffffff1684860152606082019390935291825260030154918101919091528161428b85614d6b565b82515190915064ffffffffff1615806142a2575080155b156142b257600092505050610ccf565b815160200151604051630b27cfb160e31b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906142f690610290908690600401615c21565b6040805180830381865af4158015614312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143369190615c45565b60405163038255fd60e11b8152610290600482015290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af415801561438c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b09190615c90565b90508460200151955073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5384836040518363ffffffff1660e01b81526004016143f2929190615cbc565b602060405180830381865af415801561440f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144339190615aec565b61474457604051633e1e5c5360e11b815260009073__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a690614471908790600401615cf0565b6040805180830381865af415801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615c90565b604051630b27cfb160e31b815290915060009073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906144f290610290908690600401615c21565b6040805180830381865af415801561450e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145329190615c45565b87515160208201518651929350614560928c61454f576000614551565b8b5b61455b908b615843565b614e14565b61456a9089615843565b97505b81945080935073__$3728f51d90da6977d2525dcec632daa0b3$__634ead0c5386856040518363ffffffff1660e01b81526004016145ac929190615cbc565b602060405180830381865af41580156145c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145ed9190615aec565b61471757604051633e1e5c5360e11b815273__$3728f51d90da6977d2525dcec632daa0b3$__90637c3cb8a690614628908890600401615cf0565b6040805180830381865af4158015614644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146689190615c90565b604051630b27cfb160e31b815290925073__$3728f51d90da6977d2525dcec632daa0b3$__9063593e7d88906146a690610290908690600401615c21565b6040805180830381865af41580156146c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e69190615c45565b90506147068460200151826020015186600001518c61454f576000614551565b6147109089615843565b975061456d565b61473184602001514286600001518c61454f576000614551565b61473b9089615843565b97505050614775565b8451518251614768919042908a61475c57600061475e565b895b61455b9089615843565b6147729087615843565b95505b505050505092915050565b600054610100900460ff166147a75760405162461bcd60e51b8152600401610d1590615aa1565b6147af61480b565b6147b883614f00565b6147c0614f30565b6147c982614f5f565b6147d281614fa9565b6118a761480b565b600054610100900460ff166148015760405162461bcd60e51b8152600401610d1590615aa1565b6119788282614ff3565b600054610100900460ff166134e35760405162461bcd60e51b8152600401610d1590615aa1565b600054610100900460ff166148595760405162461bcd60e51b8152600401610d1590615aa1565b306001600160a01b038216036148b15760405162461bcd60e51b815260206004820152601e60248201527f4552433230577261707065723a2063616e6e6f742073656c66207772617000006044820152606401610d15565b6102c680546001600160a01b0319166001600160a01b0392909216919091179055565b6148df838383615033565b6001600160a01b038316156148f9576148f9836001613f88565b6001600160a01b038216156118a7576118a7826001613f88565b6001600160a01b038316158061493057506001600160a01b038216155b15614970577f980f7e6fb44009001d533a10bc3bd558b4efe22dcb4888bca4767aa93c71ce1f61495e61100c565b60405190815260200160405180910390a15b60005b6103025481101561367757610302818154811061499257614992615856565b600091825260209091200154604051636e0d037d60e11b81526001600160a01b0386811660048301528581166024830152604482018590529091169063dc1a06fa90606401600060405180830381600087803b1580156149f157600080fd5b505af1158015614a05573d6000803e3d6000fd5b505050508080614a14906158e7565b915050614973565b6000614a71826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166150949092919063ffffffff16565b9050805160001480614a92575080806020019051810190614a929190615aec565b6118a75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d15565b6001600160a01b0381163b614b5e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610d15565b600080516020615e5583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b614b96836150a3565b600082511180614ba35750805b156118a75761367783836150e3565b6000826001600160a01b03167f05a71d417f891ba4b7a94b48d1b1f4b59b070921cba593b3c72a05a5587a78a9614be885612527565b60408051918252602082018690520160405180910390a2613ca88383613cb1565b6001600160a01b038116600090815261028f602052604090819020805464ffffffffff19164264ffffffffff161790555163038255fd60e11b8152610290600482015273__$3728f51d90da6977d2525dcec632daa0b3$__90630704abfa906024016040805180830381865af4158015614c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cab9190615c90565b6001600160a01b038216600090815261028f602090815260408220835160018201559201516002909201805463ffffffff191663ffffffff909316929092179091555b6001600160a01b03821660009081526102926020526040902054811015611978576001600160a01b0382166000908152610292602052604090208054614d59919083908110614d3f57614d3f615856565b6000918252602090912001546001600160a01b0316614c09565b80614d63816158e7565b915050614cee565b6000614d7682615108565b614d809082615843565b905060005b6001600160a01b03831660009081526102926020526040902054811015614e0e576001600160a01b0383166000908152610292602052604090208054614df0919083908110614dd657614dd6615856565b6000918252602090912001546001600160a01b0316614d6b565b614dfa9083615843565b915080614e06816158e7565b915050614d85565b50919050565b600080614e2d612fd361028e546001600160a01b031690565b90506000614e4b614e3e8888615d0d565b64ffffffffff16836141b5565b90506000614e5d6301e13380846141b5565b614e686001856141b5565b614e729084615a6d565b614e7c919061586c565b90506000614e8e8761ffff1685614189565b90506000614e9d6001866141b5565b614ea78385615a6d565b614eb1919061586c565b90506000614ebf888761414b565b90506000614ece6064886141b5565b614ed88484615a6d565b614ee2919061586c565b9050614eee81886141e3565b9750505050505050505b949350505050565b600054610100900460ff16614f275760405162461bcd60e51b8152600401610d1590615aa1565b6114f581615113565b600054610100900460ff16614f575760405162461bcd60e51b8152600401610d1590615aa1565b6134e361515d565b600054610100900460ff16614f865760405162461bcd60e51b8152600401610d1590615aa1565b61016080546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16614fd05760405162461bcd60e51b8152600401610d1590615aa1565b61019380546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1661501a5760405162461bcd60e51b8152600401610d1590615aa1565b609a6150268382615d78565b50609b6118a78282615d78565b61503b613839565b8261504581613881565b156150625760405162461bcd60e51b8152600401610d1590615998565b8261506c81613881565b156150895760405162461bcd60e51b8152600401610d1590615998565b612082858585615190565b6060614ef884846000856151f8565b6150ac81614af1565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606110878383604051806060016040528060278152602001615e95602791396152d3565b6000610ccf82612527565b600054610100900460ff1661513a5760405162461bcd60e51b8152600401610d1590615aa1565b61012d80546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166151845760405162461bcd60e51b8152600401610d1590615aa1565b60c9805460ff19169055565b615198611a6b565b156118a75760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610d15565b6060824710156152595760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610d15565b600080866001600160a01b031685876040516152759190615e38565b60006040518083038185875af1925050503d80600081146152b2576040519150601f19603f3d011682016040523d82523d6000602084013e6152b7565b606091505b50915091506152c88783838761534b565b979650505050505050565b6060600080856001600160a01b0316856040516152f09190615e38565b600060405180830381855af49150503d806000811461532b576040519150601f19603f3d011682016040523d82523d6000602084013e615330565b606091505b50915091506153418683838761534b565b9695505050505050565b606083156153ba5782516000036153b3576001600160a01b0385163b6153b35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d15565b5081614ef8565b614ef883838151156153cf5781518083602001fd5b8060405162461bcd60e51b8152600401610d15919061540d565b60005b838110156154045781810151838201526020016153ec565b50506000910152565b602081526000825180602084015261542c8160408501602087016153e9565b601f01601f19169190910160400192915050565b6001600160a01b03811681146114f557600080fd5b6000806040838503121561546857600080fd5b823561547381615440565b946020939093013593505050565b60006020828403121561549357600080fd5b813561108781615440565b600080600080600060a086880312156154b657600080fd5b85356154c181615440565b945060208601356154d181615440565b935060408601356154e181615440565b925060608601356154f181615440565b9150608086013561550181615440565b809150509295509295909350565b60008060006060848603121561552457600080fd5b833561552f81615440565b9250602084013561553f81615440565b929592945050506040919091013590565b60006020828403121561556257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156155a2576155a2615569565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156155d1576155d1615569565b604052919050565b600067ffffffffffffffff8211156155f3576155f3615569565b50601f01601f191660200190565b6000806040838503121561561457600080fd5b823561561f81615440565b9150602083013567ffffffffffffffff81111561563b57600080fd5b8301601f8101851361564c57600080fd5b803561565f61565a826155d9565b6155a8565b81815286602083850101111561567457600080fd5b816020840160208301376000602083830101528093505050509250929050565b61ffff811681146114f557600080fd5b6000602082840312156156b657600080fd5b813561108781615694565b600080604083850312156156d457600080fd5b82356156df81615440565b915060208301356156ef81615440565b809150509250929050565b63ffffffff811681146114f557600080fd5b60006020828403121561571e57600080fd5b8135611087816156fa565b600181811c9082168061573d57607f821691505b602082108103614e0e57634e487b7160e01b600052602260045260246000fd5b60006020828403121561576f57600080fd5b815167ffffffffffffffff81111561578657600080fd5b8201601f8101841361579757600080fd5b80516157a561565a826155d9565b8181528560208385010111156157ba57600080fd5b6157cb8260208301602086016153e9565b95945050505050565b6702632b233b4ba3c960c51b8152600082516157f78160088501602087016153e9565b9190910160080192915050565b601360fa1b8152600082516158208160018501602087016153e9565b9190910160010192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610ccf57610ccf61582d565b634e487b7160e01b600052603260045260246000fd5b60008261588957634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ccf57610ccf61582d565b600381106158bf57634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03841681526020810183905260608101614ef860408301846158a1565b6000600182016158f9576158f961582d565b5060010190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252600290820152614c3960f01b604082015260600190565b6000602082840312156159c657600080fd5b5051919050565b8381526020810183905260608101614ef860408301846158a1565b6001600160601b0384811682528316602082015260608101614ef860408301846158a1565b634e487b7160e01b600052603160045260246000fd5b600060208284031215615a3557600080fd5b815161108781615440565b600081615a4f57615a4f61582d565b506000190190565b634e487b7160e01b600052600160045260246000fd5b8082028115828204841417610ccf57610ccf61582d565b600060208284031215615a9657600080fd5b815161108781615694565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215615afe57600080fd5b8151801515811461108757600080fd5b600060208284031215615b2057600080fd5b815160ff8116811461108757600080fd5b600181815b80851115615b6c578160001904821115615b5257615b5261582d565b80851615615b5f57918102915b93841c9390800290615b36565b509250929050565b600082615b8357506001610ccf565b81615b9057506000610ccf565b8160018114615ba65760028114615bb057615bcc565b6001915050610ccf565b60ff841115615bc157615bc161582d565b50506001821b610ccf565b5060208310610133831016604e8410600b8410161715615bef575081810a610ccf565b615bf98383615b31565b8060001904821115615c0d57615c0d61582d565b029392505050565b60006110878383615b74565b8281526060810161108760208301848051825260209081015163ffffffff16910152565b600060408284031215615c5757600080fd5b615c5f61557f565b8251615c6a81615694565b8152602083015164ffffffffff81168114615c8457600080fd5b60208201529392505050565b600060408284031215615ca257600080fd5b615caa61557f565b825181526020830151615c84816156fa565b8251815260208084015163ffffffff16908201526080810182516040830152602083015163ffffffff166060830152611087565b8151815260208083015163ffffffff169082015260408101610ccf565b64ffffffffff828116828216039080821115615d2b57615d2b61582d565b5092915050565b601f8211156118a757600081815260208120601f850160051c81016020861015615d595750805b601f850160051c820191505b8181101561100457828155600101615d65565b815167ffffffffffffffff811115615d9257615d92615569565b615da681615da08454615729565b84615d32565b602080601f831160018114615ddb5760008415615dc35750858301515b600019600386901b1c1916600185901b178555611004565b600085815260208120601f198616915b82811015615e0a57888601518255948401946001909101908401615deb565b5085821015615e285787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008251615e4a8184602087016153e9565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbcfeb6a900a360475a17ff2a61d90610bd38f52b2b474c52828b8411221ff2576f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e1d4dd61867ca96be7efe83d7ca66dcd56b3ec13ae334b24d813c7fd7fe3c42d64736f6c63430008120033", - "libraries": { - "APRHistory": "0x3F0Ff9947550d7Cf26549136552C785446ad4Ac5" - }, - "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)": { - "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.", - "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)": { - "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 - }, - "storageLayout": { - "storage": [ - { - "astId": 609, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 612, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 591, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 906, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "51", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 2785, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "101", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1053, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_balances", - "offset": 0, - "slot": "151", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 1059, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_allowances", - "offset": 0, - "slot": "152", - "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" - }, - { - "astId": 1061, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_totalSupply", - "offset": 0, - "slot": "153", - "type": "t_uint256" - }, - { - "astId": 1063, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_name", - "offset": 0, - "slot": "154", - "type": "t_string_storage" - }, - { - "astId": 1065, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_symbol", - "offset": 0, - "slot": "155", - "type": "t_string_storage" - }, - { - "astId": 1645, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "156", - "type": "t_array(t_uint256)45_storage" - }, - { - "astId": 928, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_paused", - "offset": 0, - "slot": "201", - "type": "t_bool" - }, - { - "astId": 1033, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "202", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 116, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_owner", - "offset": 0, - "slot": "251", - "type": "t_address" - }, - { - "astId": 236, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "252", - "type": "t_array(t_uint256)49_storage" - }, - { - "astId": 5727, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalOwner", - "offset": 0, - "slot": "301", - "type": "t_contract(GlobalOwner)3833" - }, - { - "astId": 5811, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "302", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5829, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalPause", - "offset": 0, - "slot": "352", - "type": "t_contract(GlobalPause)3909" - }, - { - "astId": 5888, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "353", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 5902, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_globalBlacklist", - "offset": 0, - "slot": "403", - "type": "t_contract(GlobalBlacklist)3786" - }, - { - "astId": 5976, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "404", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 6995, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "454", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 7086, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "504", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1783, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "554", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 7191, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "604", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 6028, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_invested", - "offset": 0, - "slot": "654", - "type": "t_contract(IERC20Upgradeable)1724" - }, - { - "astId": 6034, - "contract": "contracts/src/LToken.sol:LToken", - "label": "accountsDetails", - "offset": 0, - "slot": "655", - "type": "t_mapping(t_address,t_struct(AccountDetails)6024_storage)" - }, - { - "astId": 6039, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_aprHistory", - "offset": 0, - "slot": "656", - "type": "t_array(t_struct(Pack)8859_storage)dyn_storage" - }, - { - "astId": 6044, - "contract": "contracts/src/LToken.sol:LToken", - "label": "rewardsRedirectsFromTo", - "offset": 0, - "slot": "657", - "type": "t_mapping(t_address,t_address)" - }, - { - "astId": 6049, - "contract": "contracts/src/LToken.sol:LToken", - "label": "rewardsRedirectsToFrom", - "offset": 0, - "slot": "658", - "type": "t_mapping(t_address,t_array(t_address)dyn_storage)" - }, - { - "astId": 6052, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_isClaiming", - "offset": 0, - "slot": "659", - "type": "t_bool" - }, - { - "astId": 6902, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "660", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 1797, - "contract": "contracts/src/LToken.sol:LToken", - "label": "_underlying", - "offset": 0, - "slot": "710", - "type": "t_contract(IERC20Upgradeable)1724" - }, - { - "astId": 1976, - "contract": "contracts/src/LToken.sol:LToken", - "label": "__gap", - "offset": 0, - "slot": "711", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 3968, - "contract": "contracts/src/LToken.sol:LToken", - "label": "ldyStaking", - "offset": 0, - "slot": "761", - "type": "t_contract(LDYStaking)3669" - }, - { - "astId": 3971, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawer", - "offset": 0, - "slot": "762", - "type": "t_address_payable" - }, - { - "astId": 3974, - "contract": "contracts/src/LToken.sol:LToken", - "label": "fund", - "offset": 0, - "slot": "763", - "type": "t_address" - }, - { - "astId": 3977, - "contract": "contracts/src/LToken.sol:LToken", - "label": "feesRateUD7x3", - "offset": 20, - "slot": "763", - "type": "t_uint32" - }, - { - "astId": 3980, - "contract": "contracts/src/LToken.sol:LToken", - "label": "retentionRateUD7x3", - "offset": 24, - "slot": "763", - "type": "t_uint32" - }, - { - "astId": 3983, - "contract": "contracts/src/LToken.sol:LToken", - "label": "unclaimedFees", - "offset": 0, - "slot": "764", - "type": "t_uint256" - }, - { - "astId": 3986, - "contract": "contracts/src/LToken.sol:LToken", - "label": "totalQueued", - "offset": 0, - "slot": "765", - "type": "t_uint256" - }, - { - "astId": 3989, - "contract": "contracts/src/LToken.sol:LToken", - "label": "usableUnderlyings", - "offset": 0, - "slot": "766", - "type": "t_uint256" - }, - { - "astId": 3994, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawalQueue", - "offset": 0, - "slot": "767", - "type": "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage" - }, - { - "astId": 3997, - "contract": "contracts/src/LToken.sol:LToken", - "label": "withdrawalQueueCursor", - "offset": 0, - "slot": "768", - "type": "t_uint256" - }, - { - "astId": 4002, - "contract": "contracts/src/LToken.sol:LToken", - "label": "frozenRequests", - "offset": 0, - "slot": "769", - "type": "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage" - }, - { - "astId": 4007, - "contract": "contracts/src/LToken.sol:LToken", - "label": "transfersListeners", - "offset": 0, - "slot": "770", - "type": "t_array(t_contract(ITransfersListener)8840)dyn_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "t_address_payable": { - "encoding": "inplace", - "label": "address payable", - "numberOfBytes": "20" - }, - "t_array(t_address)dyn_storage": { - "base": "t_address", - "encoding": "dynamic_array", - "label": "address[]", - "numberOfBytes": "32" - }, - "t_array(t_contract(ITransfersListener)8840)dyn_storage": { - "base": "t_contract(ITransfersListener)8840", - "encoding": "dynamic_array", - "label": "contract ITransfersListener[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(Pack)8859_storage)dyn_storage": { - "base": "t_struct(Pack)8859_storage", - "encoding": "dynamic_array", - "label": "struct APRHistory.Pack[]", - "numberOfBytes": "32" - }, - "t_array(t_struct(WithdrawalRequest)3951_storage)dyn_storage": { - "base": "t_struct(WithdrawalRequest)3951_storage", - "encoding": "dynamic_array", - "label": "struct LToken.WithdrawalRequest[]", - "numberOfBytes": "32" - }, - "t_array(t_uint16)4_storage": { - "base": "t_uint16", - "encoding": "inplace", - "label": "uint16[4]", - "numberOfBytes": "32" - }, - "t_array(t_uint256)45_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[45]", - "numberOfBytes": "1440" - }, - "t_array(t_uint256)49_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[49]", - "numberOfBytes": "1568" - }, - "t_array(t_uint256)50_storage": { - "base": "t_uint256", - "encoding": "inplace", - "label": "uint256[50]", - "numberOfBytes": "1600" - }, - "t_array(t_uint40)4_storage": { - "base": "t_uint40", - "encoding": "inplace", - "label": "uint40[4]", - "numberOfBytes": "32" - }, - "t_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_contract(GlobalBlacklist)3786": { - "encoding": "inplace", - "label": "contract GlobalBlacklist", - "numberOfBytes": "20" - }, - "t_contract(GlobalOwner)3833": { - "encoding": "inplace", - "label": "contract GlobalOwner", - "numberOfBytes": "20" - }, - "t_contract(GlobalPause)3909": { - "encoding": "inplace", - "label": "contract GlobalPause", - "numberOfBytes": "20" - }, - "t_contract(IERC20Upgradeable)1724": { - "encoding": "inplace", - "label": "contract IERC20Upgradeable", - "numberOfBytes": "20" - }, - "t_contract(ITransfersListener)8840": { - "encoding": "inplace", - "label": "contract ITransfersListener", - "numberOfBytes": "20" - }, - "t_contract(LDYStaking)3669": { - "encoding": "inplace", - "label": "contract LDYStaking", - "numberOfBytes": "20" - }, - "t_mapping(t_address,t_address)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => address)", - "numberOfBytes": "32", - "value": "t_address" - }, - "t_mapping(t_address,t_array(t_address)dyn_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => address[])", - "numberOfBytes": "32", - "value": "t_array(t_address)dyn_storage" - }, - "t_mapping(t_address,t_mapping(t_address,t_uint256))": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => mapping(address => uint256))", - "numberOfBytes": "32", - "value": "t_mapping(t_address,t_uint256)" - }, - "t_mapping(t_address,t_struct(AccountDetails)6024_storage)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => struct InvestUpgradeable.AccountDetails)", - "numberOfBytes": "32", - "value": "t_struct(AccountDetails)6024_storage" - }, - "t_mapping(t_address,t_uint256)": { - "encoding": "mapping", - "key": "t_address", - "label": "mapping(address => uint256)", - "numberOfBytes": "32", - "value": "t_uint256" - }, - "t_string_storage": { - "encoding": "bytes", - "label": "string", - "numberOfBytes": "32" - }, - "t_struct(AccountDetails)6024_storage": { - "encoding": "inplace", - "label": "struct InvestUpgradeable.AccountDetails", - "members": [ - { - "astId": 6021, - "contract": "contracts/src/LToken.sol:LToken", - "label": "period", - "offset": 0, - "slot": "0", - "type": "t_struct(InvestmentPeriod)6018_storage" - }, - { - "astId": 6023, - "contract": "contracts/src/LToken.sol:LToken", - "label": "virtualBalance", - "offset": 0, - "slot": "3", - "type": "t_uint256" - } - ], - "numberOfBytes": "128" - }, - "t_struct(InvestmentPeriod)6018_storage": { - "encoding": "inplace", - "label": "struct InvestUpgradeable.InvestmentPeriod", - "members": [ - { - "astId": 6014, - "contract": "contracts/src/LToken.sol:LToken", - "label": "timestamp", - "offset": 0, - "slot": "0", - "type": "t_uint40" - }, - { - "astId": 6017, - "contract": "contracts/src/LToken.sol:LToken", - "label": "ref", - "offset": 0, - "slot": "1", - "type": "t_struct(Reference)8864_storage" - } - ], - "numberOfBytes": "96" - }, - "t_struct(Pack)8859_storage": { - "encoding": "inplace", - "label": "struct APRHistory.Pack", - "members": [ - { - "astId": 8852, - "contract": "contracts/src/LToken.sol:LToken", - "label": "aprsUD7x3", - "offset": 0, - "slot": "0", - "type": "t_array(t_uint16)4_storage" - }, - { - "astId": 8856, - "contract": "contracts/src/LToken.sol:LToken", - "label": "timestamps", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint40)4_storage" - }, - { - "astId": 8858, - "contract": "contracts/src/LToken.sol:LToken", - "label": "cursor", - "offset": 0, - "slot": "2", - "type": "t_uint32" - } - ], - "numberOfBytes": "96" - }, - "t_struct(Reference)8864_storage": { - "encoding": "inplace", - "label": "struct APRHistory.Reference", - "members": [ - { - "astId": 8861, - "contract": "contracts/src/LToken.sol:LToken", - "label": "packIndex", - "offset": 0, - "slot": "0", - "type": "t_uint256" - }, - { - "astId": 8863, - "contract": "contracts/src/LToken.sol:LToken", - "label": "cursorIndex", - "offset": 0, - "slot": "1", - "type": "t_uint32" - } - ], - "numberOfBytes": "64" - }, - "t_struct(WithdrawalRequest)3951_storage": { - "encoding": "inplace", - "label": "struct LToken.WithdrawalRequest", - "members": [ - { - "astId": 3948, - "contract": "contracts/src/LToken.sol:LToken", - "label": "account", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 3950, - "contract": "contracts/src/LToken.sol:LToken", - "label": "amount", - "offset": 20, - "slot": "0", - "type": "t_uint96" - } - ], - "numberOfBytes": "32" - }, - "t_uint16": { - "encoding": "inplace", - "label": "uint16", - "numberOfBytes": "2" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint32": { - "encoding": "inplace", - "label": "uint32", - "numberOfBytes": "4" - }, - "t_uint40": { - "encoding": "inplace", - "label": "uint40", - "numberOfBytes": "5" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - }, - "t_uint96": { - "encoding": "inplace", - "label": "uint96", - "numberOfBytes": "12" - } - } - } -} diff --git a/contracts/src/DummyLDYStaking.sol b/contracts/src/DummyLDYStaking.sol index 3bd2047e..b154d824 100644 --- a/contracts/src/DummyLDYStaking.sol +++ b/contracts/src/DummyLDYStaking.sol @@ -8,8 +8,8 @@ import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @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. * * @dev This contract only implements tierOf() function from LDYStaking as it's the only * one the LToken contract relies on. @@ -34,8 +34,8 @@ contract LDYStaking is Ownable2Step { /** * @dev 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. + * elligible to any LDY staking tier, except if the account is in the + * highTierAccounts mapping. * @param account The account to check the tier of. */ function tierOf(address account) public view returns (uint256 tier) { diff --git a/contracts/src/GlobalBlacklist.sol b/contracts/src/GlobalBlacklist.sol index f76a41b2..80394f0c 100644 --- a/contracts/src/GlobalBlacklist.sol +++ b/contracts/src/GlobalBlacklist.sol @@ -10,9 +10,8 @@ import {GlobalOwnableUpgradeable} from "./abstracts/GlobalOwnableUpgradeable.sol * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @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. * * @dev Specifically, some contracts within the codebase inherit from the * GlobalRestrictableUpgradeable abstract contract. This provides them with modifiers diff --git a/contracts/src/GlobalOwner.sol b/contracts/src/GlobalOwner.sol index 85e943e8..c613893a 100644 --- a/contracts/src/GlobalOwner.sol +++ b/contracts/src/GlobalOwner.sol @@ -10,7 +10,7 @@ import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/acces * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Maintains the address of a global owner account shared by all contracts of the + * @notice Holds the address of a global owner account shared by all contracts of the * Ledgity Yield's codebase. * * @dev Specifically, some contracts within the codebase inherit from the diff --git a/contracts/src/GlobalPause.sol b/contracts/src/GlobalPause.sol index 690d4f06..1245711a 100644 --- a/contracts/src/GlobalPause.sol +++ b/contracts/src/GlobalPause.sol @@ -11,7 +11,7 @@ import {GlobalOwnableUpgradeable} from "./abstracts/GlobalOwnableUpgradeable.sol * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Maintains a global pause state shared by all contracts of the Ledgity Yield + * @notice Holds a global pause state shared by all contracts of the Ledgity Yield * codebase. * * @dev Specifically, some contracts within the codebase inherit from the diff --git a/contracts/src/LToken.sol b/contracts/src/LToken.sol index 8ab72d98..9dac7c3b 100644 --- a/contracts/src/LToken.sol +++ b/contracts/src/LToken.sol @@ -21,7 +21,7 @@ import {ITransfersListener} from "./interfaces/ITransfersListener.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Main contract of the Ledgity Yield protocol. It powers every L-Token (i.e, + * @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. @@ -30,14 +30,14 @@ import {ITransfersListener} from "./interfaces/ITransfersListener.sol"; * - 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: 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 that the contract can retain. + * - 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 as safe to use by the contract. + * 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 @@ -45,9 +45,10 @@ import {ITransfersListener} from "./interfaces/ITransfersListener.sol"; * * Note that words between parenthesis are sometimes omitted for brevity. * - * @dev 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. + * @dev 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. * * @dev For further details, see "LToken" section of whitepaper. * @custom:oz-upgrades-unsafe-allow external-library-linking diff --git a/contracts/src/LTokenSignaler.sol b/contracts/src/LTokenSignaler.sol index 6546d21a..ce27ac2b 100644 --- a/contracts/src/LTokenSignaler.sol +++ b/contracts/src/LTokenSignaler.sol @@ -11,7 +11,7 @@ import {GlobalOwnableUpgradeable} from "./abstracts/GlobalOwnableUpgradeable.sol * @custom:security-contact security@ledgity.com * * @notice Used to inform subgraph from the existence of a new L-Token contract. Once - * signaled, a L-Token it will start being indexed. + * signaled, a L-Token will start being indexed. * * @dev Signal are ignored by the subgraph if the L-Token is already known by it. * diff --git a/contracts/src/abstracts/GlobalOwnableUpgradeable.sol b/contracts/src/abstracts/GlobalOwnableUpgradeable.sol index 799e16a7..e0e417fd 100644 --- a/contracts/src/abstracts/GlobalOwnableUpgradeable.sol +++ b/contracts/src/abstracts/GlobalOwnableUpgradeable.sol @@ -14,8 +14,9 @@ import {GlobalOwner} from "../GlobalOwner.sol"; * contract (see GlobalOwner.sol). This design facilitates centralized management * of ownership for all the Ledgity Yield contracts. * - * @dev Note: The _globalOwner state must be set at initialization-time and for evident - * security reasons cannot be changed afterwards. + * @dev Security measure: + * The _globalOwner state must be set at initialization time and, for evident security + * reasons, cannot be changed afterward. * * @dev For further details, see "GlobalOwnableUpgradeable" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/abstracts/GlobalPausableUpgradeable.sol b/contracts/src/abstracts/GlobalPausableUpgradeable.sol index 8bd02562..2593d290 100644 --- a/contracts/src/abstracts/GlobalPausableUpgradeable.sol +++ b/contracts/src/abstracts/GlobalPausableUpgradeable.sol @@ -10,12 +10,13 @@ import {GlobalPause} from "../GlobalPause.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Derived contracts will inherit pause state from the specified GlobalPause + * @notice Derived contracts will inherit a pause state from the specified GlobalPause * contract (see GlobalPause.sol). This design facilitates centralized management of * pause state for all the Ledgity Yield contracts. * - * @dev Note: The _globalPause state must be set at initialization-time and for evident - * security reasons cannot be changed afterwards. + * @dev Security measure + * The _globalPause state must be set at initialization time and, for evident security + * reasons, cannot be changed afterward. * * @dev For further details, see "GlobalPausableUpgradeable" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/abstracts/GlobalRestrictableUpgradeable.sol b/contracts/src/abstracts/GlobalRestrictableUpgradeable.sol index d8c333b8..cd013f71 100644 --- a/contracts/src/abstracts/GlobalRestrictableUpgradeable.sol +++ b/contracts/src/abstracts/GlobalRestrictableUpgradeable.sol @@ -9,12 +9,13 @@ import {GlobalBlacklist} from "../GlobalBlacklist.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Derived contracts will inherit blacklist state from the specified + * @notice Derived contracts will inherit a blacklist state from the specified * GlobalBlacklist contract (see GlobalBlacklist.sol). This design facilitates * centralized management of a blacklist for all the Ledgity Yield contracts. * - * @dev Note: The _globalBlacklist state must be set at initialization-time and for - * evident security reasons cannot be changed afterwards. + * @dev Security measure: + * The _globalBlacklist state must be set at initialization time and, for evident + * security reasons, cannot be changed afterward. * * @dev For further details, see "GlobalRestrictableUpgradeable" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/abstracts/InvestUpgradeable.sol b/contracts/src/abstracts/InvestUpgradeable.sol index f708fa57..8a69afd9 100644 --- a/contracts/src/abstracts/InvestUpgradeable.sol +++ b/contracts/src/abstracts/InvestUpgradeable.sol @@ -34,8 +34,7 @@ import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/tok * * @dev Definitions: * - Investment: The act of depositing or investing tokens into the contract. - * - Investment period: Time between the start of an investment or the last rewards - * distribution for an account to the present. + * - Investment period: Time between the last invested amount change and the present. * - Virtual balance: Temporary storage for account rewards, used when those can't be * distributed between investment periods. * - Rewards redirection: Mechanism allowing an account to redirect its rewards to another. @@ -43,7 +42,7 @@ import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/tok * @dev Derived contract must: * - Set invested token during initialization * - Implement _investmentOf() function - * - Implement _distributeRewards() function (optional) + * - (optionally) Implement _distributeRewards() function * * @dev For further details, see "InvestmentUpgradeable" section of whitepaper. * @custom:security-contact security@ledgity.com @@ -324,7 +323,7 @@ abstract contract InvestUpgradeable is BaseUpgradeable { APRH.Reference memory latestRef = _aprHistory.getLatestReference(); // 1) Fill rewards with virtual balance (rewards not claimed/distributed yet) - // See "InvestUpgradeable > Rewards calculation > 1)" section of the whitepaper + // See "InvestUpgradeable > Yield calculation > 1)" section of the whitepaper rewards = details.virtualBalance; // If start checkpoint is not the latest one @@ -334,7 +333,7 @@ abstract contract InvestUpgradeable is BaseUpgradeable { APRH.CheckpointData memory nextCheckpoint = _aprHistory.getDataFromReference(nextRef); // 2) Calculate rewards from investment period start to next checkpoint - // See "InvestUpgradeable > Rewards calculation > 2)" section of the whitepaper + // See "InvestUpgradeable > Yield calculation > 2)" section of the whitepaper rewards += _calculatePeriodRewards( details.period.timestamp, nextCheckpoint.timestamp, @@ -343,7 +342,7 @@ abstract contract InvestUpgradeable is BaseUpgradeable { ); // 3) Calculate rewards for each crossed pair of checkpoints - // See "InvestUpgradeable > Rewards calculation > 3)" section of the whitepaper + // See "InvestUpgradeable > Yield calculation > 3)" section of the whitepaper while (true) { // Set next checkpoint as the current one currRef = nextRef; @@ -366,7 +365,7 @@ abstract contract InvestUpgradeable is BaseUpgradeable { } // 4) Calculate rewards from the latest checkpoint to now - // See "InvestUpgradeable > Rewards calculation > 4)" section of the whitepaper + // See "InvestUpgradeable > Yield calculation > 4)" section of the whitepaper rewards += _calculatePeriodRewards( currCheckpoint.timestamp, uint40(block.timestamp), @@ -375,7 +374,7 @@ abstract contract InvestUpgradeable is BaseUpgradeable { ); } else { // 2.bis) Calculate rewards from investment period start to now - // See "InvestUpgradeable > Rewards calculation > 2.bis)" section of the whitepaper + // See "InvestUpgradeable > Yield calculation > 2.bis)" section of the whitepaper rewards += _calculatePeriodRewards( details.period.timestamp, uint40(block.timestamp), diff --git a/contracts/src/abstracts/RecoverableUpgradeable.sol b/contracts/src/abstracts/RecoverableUpgradeable.sol index a561033d..2aebd82e 100644 --- a/contracts/src/abstracts/RecoverableUpgradeable.sol +++ b/contracts/src/abstracts/RecoverableUpgradeable.sol @@ -16,12 +16,13 @@ import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20 * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice Derived contracts are provided with helpers functions that allow recovering + * @notice Derived contracts are provided with helper functions allowing the recovery of * assets accidentally sent to them. * - * @dev Note: This abstract contract currently supports only ERC20 tokens. Derived - * contracts currently do not implement necessary functions to receive Ether or - * ERC721/ERC1155 tokens. + * @dev Where are utilities Ether, ERC721, etc.? + * This abstract contract currently supports only ERC20 tokens. Derived contracts + * in this codebase currently do not implement the necessary functions to receive Ether + * or ERC721/ERC1155 tokens, so no recovery functions are provided for these assets. * * @dev For further details, see "RecoverableUpgradeable" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/abstracts/base/BaseUpgradeable.sol b/contracts/src/abstracts/base/BaseUpgradeable.sol index 005500e3..28d088fa 100644 --- a/contracts/src/abstracts/base/BaseUpgradeable.sol +++ b/contracts/src/abstracts/base/BaseUpgradeable.sol @@ -13,8 +13,8 @@ import {RecoverableUpgradeable} from "../RecoverableUpgradeable.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice This abstract contract acts as a base for numerous contracts contract in this - * codebase, minimizing code repetition and enhancing readability and maintainability. + * @notice This abstract contract acts as a base for numerous contracts in this codebase, + * minimizing code repetition and enhancing readability and maintainability. * * @dev For further details, see "Base" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/abstracts/base/ERC20BaseUpgradeable.sol b/contracts/src/abstracts/base/ERC20BaseUpgradeable.sol index 9f22b186..ad3e67a9 100644 --- a/contracts/src/abstracts/base/ERC20BaseUpgradeable.sol +++ b/contracts/src/abstracts/base/ERC20BaseUpgradeable.sol @@ -12,7 +12,7 @@ import {GlobalPausableUpgradeable} from "../GlobalPausableUpgradeable.sol"; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @notice This abstract contracts is an extension of BaseUpgradeable intended to be used + * @notice This abstract contract is an extension of BaseUpgradeable intended to be used * as a base for ERC20 tokens contracts. * * @dev For further details, see "ERC20BaseUpgradeable" section of whitepaper. diff --git a/contracts/src/libs/APRHistory.sol b/contracts/src/libs/APRHistory.sol index 2e6e2754..ff291032 100644 --- a/contracts/src/libs/APRHistory.sol +++ b/contracts/src/libs/APRHistory.sol @@ -6,17 +6,18 @@ pragma solidity ^0.8.18; * @author Lila Rest (https://lila.rest) * @custom:security-contact security@ledgity.com * - * @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". * * @dev Intuition: - * Each checkpoint in an APR history consists in two data: + * Each checkpoint in an APR history consists of 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. + * 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. @@ -28,8 +29,9 @@ pragma solidity ^0.8.18; * - Reference: A storage pointer to a checkpoint in the APR history * - CheckpointData: An in-memory representation of a checkpoint data * - * @dev 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%. + * @dev Value 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%. * * @dev For further details, see "APRHistory" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/contracts/src/libs/SUD.sol b/contracts/src/libs/SUD.sol index c3d159fb..32f026f1 100644 --- a/contracts/src/libs/SUD.sol +++ b/contracts/src/libs/SUD.sol @@ -13,8 +13,8 @@ import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/tok * facilitates conversions between various number formats and the SUD format. * * @dev Intuition: - * This codebase employs UD (unsigned decimal fixed-point numbers) format to represent - * both percentage rates and tokens amounts. + * This codebase employs the UD (unsigned decimal fixed-point numbers) format to + * represent both percentage rates and tokens amounts. * * Rates are expressed in UD7x3 format, whereas the format for tokens amounts depends on * the decimals() value of the involved tokens. @@ -45,7 +45,8 @@ import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/tok * rates are represented by UD7x3, a SUD number has at least 6 decimals (3+3) and * so ranges from UD71x6 to UD0x77 formats. * - * @dev This library provides utilities to perform the following conversions: + * @dev A conversion library: + * This library provides utilities to perform the following conversions: * - Amount <--> SUD * - Rate (UD7x3) <--> SUD * - Integer <--> SUD @@ -55,18 +56,19 @@ import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/tok * - It enables the conversion of a UD7x3 rate to SUD format by merely scaling it up by * the involved token's decimal number, so is gas efficient. * - * @dev Optimization note: The functions of this library are not set to external because - * incorporating them directly into contracts is more gas-efficient. Given their minimal - * size and frequent usage in the InvestUpgradeable, LDYStaking, and LToken contracts, - * any bytecode savings from making them external are negated by the additional bytecode - * required for external calls to this library. - * The can be observed by comparing the output of `pnpm cc:size` when those functions's - * visibility is set to external or internal. + * @dev Why internal functions? + * The functions of this library are not set to external because incorporating them + * directly into contracts is more gas-efficient. Given their minimal size and frequent + * usage in the InvestUpgradeable, LDYStaking, and LToken contracts, any bytecode savings + * from making them external are negated by the additional bytecode required for external + * calls to this library. This can be observed by comparing the output of `bun cc:size` + * when those functions's visibility is set to external or internal. * - * @dev Precision note: While this library mitigates precision loss during calculations - * on UD numbers, it's important to note that tokens with lower decimal counts and supply - * inherently suffer more from precision loss. Conversely, tokens with higher decimal - * counts and supply will experience less precision loss. + * @dev Precision warning: + * While this library mitigates precision loss during calculations on UD numbers, it's + * important to note that tokens with lower decimal counts and supply inherently suffer + * more from precision loss. Conversely, tokens with higher decimal counts and supply + * will experience less precision loss. * * @dev For further details, see "SUD" section of whitepaper. * @custom:security-contact security@ledgity.com diff --git a/docs/contracts-deployment-upgrade.md b/docs/contracts-deployment-upgrade.md deleted file mode 100644 index 2ac5ebef..00000000 --- a/docs/contracts-deployment-upgrade.md +++ /dev/null @@ -1,16 +0,0 @@ -# Contracts deployment and upgrade - -## Initial deployment - -Run `pnpm hardhat deploy --network ` to deploy all protocol's contracts on a given network - -## Additional deployment - -In case a new contract/deployment is added to the code base (e.g., a new L-Token), the above command can also be used to deploy it as it won't try to re-deploy already deployed contracts. - -## Upgrade - -1. Copy current implementation `.json` files from `contracts/hardhat/deployments/` to `contracts/hardhat/archive/` -2. Run `pnpm hardhat deploy --network ` to deploy the new implementation -3. Propose the new implementation using OpenZeppelin Defender, to the multisig owner -4. Verify the new implementation on Etherscan/Arbiscan, etc. diff --git a/docs/contracts-verification.md b/docs/contracts-verification.md deleted file mode 100644 index d337c570..00000000 --- a/docs/contracts-verification.md +++ /dev/null @@ -1,6 +0,0 @@ -1. Run `pnpm hardhat etherscan-verify --network --solc-input` - -- This command will fail to verify L-Token implementation (unless the bug is fixed) - -2. To verify the implementation of a L-Token run: `npx hardhat verify --network ` -3. Finally, proxy need to b diff --git a/docs/deploy-LToken.md b/docs/deploy-LToken.md deleted file mode 100644 index b999555a..00000000 --- a/docs/deploy-LToken.md +++ /dev/null @@ -1,7 +0,0 @@ -# Deploying a new L-Token - -1. Copy / paste `hardhat/scripts/deploy-LGENERIC.ts` into `hardhat/scripts/deploy-L{tokenSymbol}.ts` -2. Replace any occurence of `GENERIC` with by underlying token symbol -3. Add new L-Token into `hardhat/scripts/initial-deploy-all.ts` (in case this new token is later part of the initial deployment on a new network) -4. Add underlying token addresses into `hardhat/deployments.ts` (else deployment will fail) -5. Run `hardhat run --network {network} hardhat/scripts/deploy-L{tokenSymbol}.ts` diff --git a/docs/local-subgraph-development.md b/docs/local-subgraph-development.md deleted file mode 100644 index dbe73c44..00000000 --- a/docs/local-subgraph-development.md +++ /dev/null @@ -1,9 +0,0 @@ -1. Be in the root of the repo -2. If Linux computer, run `.thegraph/local-node/setup.sh` -3. Run `pnpm graph:local-node`. The local node should start. -4. Create a new local subgraph with `pnpm graph:local-create` -5. Deploy it with `pnpm graph:local-deploy` - -Resources: - -- https://thegraph.academy/developers/local-development/ diff --git a/docs/run-frontend-locally.md b/docs/run-frontend-locally.md deleted file mode 100644 index 641ad7a0..00000000 --- a/docs/run-frontend-locally.md +++ /dev/null @@ -1,7 +0,0 @@ -The local environement relies on Bun as a package manager, but still uses Node.js to run the code as Bun runtime is still unstable with the React and Next.js ecosystems. - -To get the frontend running locally, you need to: -1. Ensure Node.js is installed on your machine ([download page](https://nodejs.org/en/download)) -2. Ensure Bun is installed on your machine ([installation page](https://bun.sh/docs/installation)) -3. Install dependencies with `bun i` -4. Run the frontend with `bun dev` \ No newline at end of file diff --git a/docs/run-slither-tests.md b/docs/run-slither-tests.md deleted file mode 100644 index b6d5b83e..00000000 --- a/docs/run-slither-tests.md +++ /dev/null @@ -1,4 +0,0 @@ -1. Ensure you have Python 3.8+ installed ([get the latest version here](https://www.python.org/downloads/)) -2. If you're using Python 3.12, manually install `setuptools` which is not bundled by default anymore: `pip3 install setuptools` -3. You're ready to get a Slither report with `bun cc:slither:report` -4. You can then perform a triage of the findings with `bun cc:slither:triage` \ No newline at end of file diff --git a/docs/ui.md b/docs/ui.md deleted file mode 100644 index 3368cfeb..00000000 --- a/docs/ui.md +++ /dev/null @@ -1,77 +0,0 @@ -# UI - -This DApp frontend relies on Tailwind CSS and Radix UI for its UI components. - -Radix UI provides unstyled low-level primitives for common UI components. Those primitives implement basic components features while strictly following the [WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/) whenever possible. This allows to quickly build accessible and fully functional components, while being entirely free in term of styling. - -The whole UI kit is accessible at [localhost:3000/ui](http://localhost:3000/ui) (or equivalent URL in production). - -## Particularities - -### CSS variables in `tailwind.config.js` file - -A common way of defining custom colors and other values in Tailwind is to use [CSS variables](https://tailwindcss.com/docs/customizing-colors#using-css-variables) in the `global.css` file. - -```css -@layer base { - :root { - --background: theme(colors.white); - --text: theme(colors.black); - } - .dark { - --background: theme(colors.black); - --text: theme(colors.white); - } -``` - -This is a pretty convenient way as it allows to condition the variables values based on the current theme (light or dark) and so helps reducing the amount of written Tailwind classes. (e.g. `bg-background` instead of `bg-background-light dark:bg-background-dark`) - -However this method has a drawback, if a non-RGB value is used, it will break the Tailwind [shorthand opacity modifier](https://tailwindcss.com/docs/background-color#changing-the-opacity) (e.g. `bg-primary/80`). -See: https://github.com/tailwindlabs/tailwindcss/issues/1692 - -Supporting opacity shorthand modifier is highly important as if for some properties like `bg` it is also possible to use the `bg-opacity-` class to modify opacity, for some other like `border-color` there is no way to do so without the shorthand modifier (as there is no `border-opacity` CSS property). - -> _What does the shorthand opacity does under the hood is that it adds an alpha channel to the provided color, which allows it to work on any color-related property, no matter if they have an opacity property or not._ - -Also, the opacity shorthand modifier removes the requirement of creating many pre-defined colors variable for each state (e.g., hovered, focused, disabled, etc.). Only a base single color is needed and can then be derived for any use case using the shortand opacity modifier. - -In order to be able to use the opacity shorthand modifier and non-RGB values, CSS variables have been defined in `tailwind.config.js` instead, which are then inserted using a minimal Tailwind plugin (inspired from [this post](https://github.com/tailwindlabs/tailwindcss/discussions/8751)). So the above example becomes: - -```js -import plugin from "tailwindcss/plugin"; -import colors from "tailwindcss/colors"; -import { parseColor } from "tailwindcss/lib/util/color"; -const toRGB = (val) => parseColor(val).color.join(" "); - -const vars = { - ":root": { - "--background": toRGB(colors.white), - "--text": toRGB(colors.black), - }, - ".dark": { - "--background": toRGB(colors.black), - "--text": toRGB(colors.white), - }, -}; -export const theme = { - // ... -}; - -export const plugins = [plugin(({ addBase }) => addBase(vars))]; -``` - -This allows using JS to convert native Tailwind colors to RGB and has also the indirect advantage of grouping all the theme-related code in a single file. - -## Standard - -### Colors - -Use the colors defined in the `tailwind.config.js` whenever possible. - -### Radius - -Use the radius defined in the `tailwind.config.js` whenever possible. - -### Hover effects - -It is recommended to use a 80% opacity for to illustrate a hover effect (e.g. `bg-primary hover:bg-primary/80`). diff --git a/docs/upgrade-safe-libraries.md b/docs/upgrade-safe-libraries.md deleted file mode 100644 index ec7c2c93..00000000 --- a/docs/upgrade-safe-libraries.md +++ /dev/null @@ -1,24 +0,0 @@ -# Upgrade-safe libraries - -In order to save up some size to deployed contracts bytecode, it is a common practice to make all the functions of a library `public` or `external`. -This leads to the the library being deployed independantly on-chain instead of being included in contracts bytecodes. -Instead the contracts use the `DELEGATECALL` opcode to execute the library functions. - -However libraries can lead to self destruct the delegator contract or may rely on the delegator contract state structure. -Because libraries source code is not always available locally and the above dangers are difficult to figure out, the OZ team has currently chosen to disable external library linking in their upgradeables plugins. - -The `APRHheckpoint` library doesn't include any self destruct mechanism nor rely on the contract state structure directly. -Instead callers contracts have to pass a state pointers as functions arguments, which means that the library is state structure agnostic. - -Therefore, the `APRHheckpoint` library can be considered as upgrade safe. - -Hopefully, OpenZeppelin `hardhat-upgrades` plugin provides a way to enable external library linking through explicit allowance. -This is why `LToken` and `LDYStaking` contracts have this line in their Natspec documentation: - -``` -@custom:oz-upgrades-unsafe-allow external-library-linking -``` - -See: - -- https://forum.openzeppelin.com/t/upgrade-safe-libraries/13832 diff --git a/foundry.toml b/foundry.toml index b53aaa8f..c26c50cc 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,11 +9,11 @@ optimizer_runs = 200 evm_version = "london" [profile.default.fuzz] -runs = 250 +runs = 10000 [profile.default.invariant] -runs = 250 -depth = 20 +runs = 10000 +depth = 50 [profile.ci.fuzz] runs = 10000 diff --git a/hardhat.config.cts b/hardhat.config.cts index 93907a69..50d68ae5 100644 --- a/hardhat.config.cts +++ b/hardhat.config.cts @@ -88,18 +88,18 @@ const config: HardhatUserConfig = { }, }, }, - OKX_X1_testnet: { - chainId: 195, - url: "https://testrpc.x1.tech", - accounts: deployerPrivateKey ? [deployerPrivateKey] : [], - saveDeployments: true, - }, arbitrumGoerli: { chainId: 421613, url: "https://arbitrum-goerli.infura.io/v3/05368c74554249babb6f126ccf325401", accounts: deployerPrivateKey ? [deployerPrivateKey] : [], saveDeployments: true, }, + OKX_X1_testnet: { + chainId: 195, + url: "https://testrpc.x1.tech", + accounts: deployerPrivateKey ? [deployerPrivateKey] : [], + saveDeployments: true, + }, }, etherscan: { apiKey: { diff --git a/package.json b/package.json index e5dc7a9a..2231bfc7 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "start": "next start", "lint": "next lint", "cc:test": "forge test -vvv --use 0.8.18", - "cc:coverage": "forge coverage", + "cc:coverage": "bash scripts/coverage.sh", "cc:size": "hardhat size-contracts", "cc:slither:report": "slither . --compile-force-framework hardhat --checklist > report.md ", "cc:slither:triage": "slither . --compile-force-framework hardhat --triage-mode", diff --git a/scripts/coverage.sh b/scripts/coverage.sh new file mode 100644 index 00000000..9b63194e --- /dev/null +++ b/scripts/coverage.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +forge coverage --report lcov + +if ! command -v lcov &>/dev/null; then + echo "'lcov' is not installed. Please install it and try again." +fi + +lcov --rc branch_coverage=1 \ + --output-file lcov.info \ + --remove lcov.info "*test*" "node_modules" "LTokenSignaler.sol" "PreMining.sol" \ + --quiet + +genhtml --flat --quiet --rc branch_coverage=1 \ + --output-directory coverage lcov.info \ + && open coverage/index.html \ No newline at end of file